Skip to content

[Due for payment 2026-04-14] [$250] Android - Accounting - Error message overlapped by OS navigation buttons #84841

Closed

Description

@jponikarchuk

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: v9.3.35-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: https://test-management.browserstack.com/projects/2219752/folder/13176908/test-cases/41237444
Email or phone of affected tester (no customers): testexpensify9+kdii@gmail.com
Issue reported by: Applause Internal Team
Bug source: Regression TC Execution
Device used: Android 16, Samsung A15.
App Component: Workspace Settings

Action Performed:

Preconditions:

  • The user has a workspace.
  • QBO UK is connected in accounting.
  1. Open the app.
  2. Go to Workspaces > {select the WS with QBO UK connected} > Accounting > Export > Export out-of-pocket expenses > Export as > Vendor bill

Expected Result:

When selecting Vendor Bill in Export as, the error message should be displayed clearly and fully visible to allow the user tap on X to close it.

Actual Result:

After selecting Vendor Bill in Export as, the error message is partially hidden/overlapped by the OS navigation buttons.

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari

Screenshots/Videos

Bug7098479_1773111576663.expensifial_account.mp4
Image

View all open jobs on GitHub

Issue OwnerCurrent Issue Owner: @mallenexpensify
Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~022031619974317786098
  • Upwork Job ID: 2031619974317786098
  • Last Price Increase: 2026-03-18
  • Automatic offers:
    • FitseTLT | Contributor | 110868793

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Mar 11, 2026
  2. melvin-bot commented on Mar 11, 2026

    @melvin-bot

    Triggered auto assignment to @laurenreidexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

  3. MelvinBot commented on Mar 11, 2026

    @MelvinBot
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    On Android, when selecting "Vendor Bill" in the QBO UK export settings (Workspaces > Accounting > Export > Export out-of-pocket expenses > Export as), the error message that appears is partially hidden behind the Android OS navigation buttons, making the dismiss (X) button inaccessible.

    What is the root cause of that problem?

    The SelectionScreen component disables bottom safe area padding on the SelectionList whenever errors are present, but the ErrorMessageRow that replaces it has no safe area padding of its own.

    Specifically, in src/components/SelectionScreen.tsx:186:

    addBottomSafeAreaPadding={!errors || isEmptyObject(errors)}
    

    When errors exist, this evaluates to false. This means the outer View in BaseSelectionList (at src/components/SelectionList/BaseSelectionList.tsx:532) does not apply bottom safe area padding:

    <View style={[styles.flex1, addBottomSafeAreaPadding && !hasFooter && paddingBottomStyle, ...]}>
    

    The ErrorMessageRow is rendered as children at line 565 of BaseSelectionList, positioned after the FlashList but with no bottom safe area inset applied to it. Meanwhile, ScreenWrapper is in edge-to-edge mode (enableEdgeToEdgeBottomSafeAreaPadding at SelectionScreen.tsx:157), which explicitly delegates bottom safe area responsibility to child components. Since no component in the hierarchy adds the padding when errors are showing, the error message sits flush at the bottom of the screen and gets overlapped by Android's navigation bar.

    What changes do you think we should make in order to solve the problem?

    In src/components/SelectionScreen.tsx, change addBottomSafeAreaPadding to always be true on the SelectionList, removing the conditional that disables it when errors exist:

    addBottomSafeAreaPadding
    

    (i.e., remove ={!errors || isEmptyObject(errors)})

    This ensures the outer container View in BaseSelectionList always applies its bottom safe area padding style, which will push the ErrorMessageRow (rendered as children) above the Android navigation bar. When there are no errors, ErrorMessageRow renders null, so the padding simply applies to the bottom of the list as it does today.

    What alternative solutions did you explore? (Optional)

    1. Adding safe area padding directly to ErrorMessageRow/MessagesRow — This would work but would require the error component to be safe-area-aware, coupling a generic UI component to platform-specific layout concerns.
    2. Moving ErrorMessageRow into footerContent instead of children — This would leverage FixedFooter's built-in safe area handling, but would change the visual layout and require refactoring how errors are passed through SelectionScreen.

    The simplest and most correct fix is option described above: always keep addBottomSafeAreaPadding enabled. The original intent of disabling it when errors show appears to have been an optimization to avoid extra padding, but the ErrorMessageRow itself doesn't compensate, creating the gap.


    Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, @MelvinBot <your feedback> to refine this analysis, or explain why you are rejecting Melvin's proposal.

  4. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Mar 11, 2026
  5. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Mar 11, 2026
  6. melvin-bot commented on Mar 11, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @Krishna2323 (External)

  7. changed the title [-]Android - Accounting - Error message overlapped by OS navigation buttons[/-] [+][$250] Android - Accounting - Error message overlapped by OS navigation buttons[/+] on Mar 11, 2026
  8. melvin-bot commented on Mar 11, 2026

    @melvin-bot
  9. shivang-goliyan commented on Mar 11, 2026

    @shivang-goliyan
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    On Android, when you select "Vendor Bill" in the QBO UK export settings, an error message appears at the bottom of the screen but gets hidden behind the OS navigation buttons. The dismiss (X) button is inaccessible, so users can't clear the error without navigating away.

    What is the root cause of that problem?

    This is a regression introduced in commit 128537cfd5b (Apr 11, 2025, "refactor: make all ConnectionLayout and SelectionScreen edge-to-edge by default").

    Before that commit, ScreenWrapper had includeSafeAreaPaddingBottom={!!errors && !isEmptyObject(errors)}, which added bottom safe area padding specifically when errors were showing. The refactor switched SelectionScreen to edge-to-edge mode (enableEdgeToEdgeBottomSafeAreaPadding at line 157), which delegates safe area responsibility to child components. The padding logic moved to SelectionList via addBottomSafeAreaPadding — but the condition got inverted.

    In SelectionScreen.tsx at line 186, addBottomSafeAreaPadding={!errors || isEmptyObject(errors)} evaluates to false when errors exist. This means BaseSelectionList's container View (line 532) skips its paddingBottomStyle, and ErrorMessageRow — rendered as {children} at line 565 with no safe area handling of its own — ends up behind Android's navigation bar.

    What changes do you think we should make in order to solve the problem?

    In src/components/SelectionScreen.tsx line 186, remove the conditional and change addBottomSafeAreaPadding={!errors || isEmptyObject(errors)} to just addBottomSafeAreaPadding.

    This way the container always applies safe area padding. When no errors exist, ErrorMessageRow renders null, so the padding applies to the list bottom — identical to current behavior. The fix is also safe when the keyboard is open (paddingBottomStyle returns false at line 118) and when a footer is present (!hasFooter check at line 532 prevents double padding).

    What alternative solutions did you explore? (Optional)

    I looked at adding useBottomSafeSafeAreaPaddingStyle directly inside ErrorMessageRow, similar to how FixedFooter handles it. This works but couples a generic UI component to platform-specific layout — and since ErrorMessageRow is used in many places, it risks double padding in contexts where the parent already provides it.

    I also considered moving ErrorMessageRow into footerContent to leverage FixedFooter's built-in safe area handling, but that changes the visual layout and introduces hasFooter side effects on the container's own padding logic. The one-line prop fix is the minimal and safest path.

  10. Ehtishamulhaq2k2 commented on Mar 11, 2026

    @Ehtishamulhaq2k2

    Hi Expensify team, I reviewed issue #84841 and I've already prepared the technical fix. We've encountered the same Android edge-to-edge overlap in production and resolved it cleanly.

    Root cause: on Android 15+ (targeting SDK 35+), the app renders edge-to-edge and the "Export as > Vendor bill" screen's bottom error message isn't applying system bar insets, so it's covered by the navigation bar.

    Fix: wrap the affected screen (or the error message container) with SafeAreaView from react-native-safe-area-context and apply the bottom edge inset:

    <SafeAreaView edges={['bottom']} style={{flex: 1}}>
    {existing content including the error message}

    This adds bottom padding equal to the navigation bar height and prevents overlap across gesture/3-button modes

  11. melvin-bot commented on Mar 11, 2026

    @melvin-bot

    📣 @Ehtishamulhaq2k2! 📣
    Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
    Please follow these steps:

    1. Make sure you've read and understood the contributing guidelines.
    2. Get the email address used to login to your Expensify account. If you don't already have an Expensify account, create one here. If you have multiple accounts (e.g. one for testing), please use your main account email.
    3. Get the link to your Upwork profile. It's necessary because we only pay via Upwork. You can access it by logging in, and then clicking on your name. It'll look like this. If you don't already have an account, sign up for one here.
    4. Copy the format below and paste it in a comment on this issue. Replace the placeholder text with your actual details.
      Screen Shot 2022-11-16 at 4 42 54 PM
      Format:
    Contributor details
    Your Expensify account email: <REPLACE EMAIL HERE>
    Upwork Profile Link: <REPLACE LINK HERE>
    
  12. 32 remaining items

  13. melvin-bot commented on Apr 7, 2026

    @melvin-bot

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.3.52-9 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

    If no regressions arise, payment will be issued on 2026-04-14. 🎊

    For reference, here are some details about the assignees on this issue:

  14. melvin-bot commented on Apr 7, 2026

    @melvin-bot

    @FitseTLT / @Krishna2323 The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]

  15. melvin-bot commented on Apr 7, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  16. melvin-bot commented on Apr 14, 2026

    @melvin-bot

    Issue is ready for payment but no BZ is assigned. @mallenexpensify you are the lucky winner! Please verify the payment summary looks correct and complete the checklist. Thanks!

  17. laurenreidexpensify commented on Apr 15, 2026

    @laurenreidexpensify
    Contributor

    Payment Summary

    $250 @FitseTLT paid in Upwork
    $250 @Krishna2323 can request in New Expensify

  18. Krishna2323 commented on Apr 17, 2026

    @Krishna2323
    Contributor

    Requested in ND.

  19. laurenreidexpensify commented on Apr 20, 2026

    @laurenreidexpensify
    Contributor

    @Krishna2323 $250 approved in New Expensify

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionBugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions