Skip to content

[$250] Reports - Going back from a replace receipt flow on a scanned expense returns to camera #82491

Closed

Description

@nlemma

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: 9.3.19-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/13176933/test-cases/41237717
Email or phone of affected tester (no customers): gatantm+626a@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: iPhone 12 mini, iOS 16.7, Google Pixel 9 Pro, Android 16
App Component: Chat Report View

Action Performed:

  1. Precondition: Scan an expense and wait for it to fail or complete
  2. Tap on Reports and select the expense that was scanned (or the report it's in and then the expense)
  3. Tap on the receipt and the overflow button
  4. Select replace
  5. Take a photo
  6. Tap back or swipe to go the previous screen

Expected Result:

User is back to main Reports screen.

Actual Result:

User is back to the camera screen to replace the receipt.
The navigation history is bugged. Works fine with a non scanned expense

Steps from @truph01 below too

  1. Create two expenses, one of which has a receipt.
  2. Tap Reports and select the expense that has the receipt.
  3. Select Replace.
  4. Take a photo.
  5. Tap Back or swipe to return to the previous screen.
  6. Observe: The user is taken back to the camera screen to replace the receipt.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7077486_1771029600284.RPReplay_Final1771029087.MP4

View all open jobs on GitHub

Issue OwnerCurrent Issue Owner: @truph01
Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~022029633533520204388
  • Upwork Job ID: 2029633533520204388
  • Last Price Increase: 2026-03-05

Activity

  1. mallenexpensify commented on Mar 5, 2026

    @mallenexpensify
    Contributor

    @truph01 this seems pretty niche. If we were to fix it, are there other similar instances we could fix at same time? Feel free to tag melvin to ask or for help.

  2. truph01 commented on Mar 5, 2026

    @truph01
    Contributor

    If we were to fix it, are there other similar instances we could fix at same time?

    @mallenexpensify Yes, the reproduction steps can be simplified as follows:

    1. Create two expenses, one of which has a receipt.
    2. Tap Reports and select the expense that has the receipt.
    3. Select Replace.
    4. Take a photo.
    5. Tap Back or swipe to return to the previous screen.

    Observe: The user is taken back to the camera screen to replace the receipt.

  3. truph01 commented on Mar 5, 2026

    @truph01
    Contributor

    As you can see, the reproduction steps for this issue are very simple and can occur quite easily. It’s not as niche as the original reproduction steps described in the OP.

  4. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Mar 5, 2026
  5. melvin-bot commented on Mar 5, 2026

    @melvin-bot

    Triggered auto assignment to @NicMendonca (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.

  6. MelvinBot commented on Mar 5, 2026

    @MelvinBot
    Contributor

    Proposal

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

    When replacing a receipt on an expense (via Reports → tap receipt → overflow menu → Replace → take photo), pressing back/swiping after capturing the photo returns the user to the camera screen instead of navigating back to the previous screen. This occurs on iOS and Android native apps.

    What is the root cause of that problem?

    The root cause is that the native navigateBack() function in IOURequestStepScan/index.native.tsx does not pass the backTo parameter to Navigation.goBack(), unlike the web version which correctly does.

    Native (index.native.tsx:80-82):

    navigateBack → Navigation.goBack()  // No backTo — just pops one screen
    

    Web (index.tsx:89-91):

    navigateBack → Navigation.goBack(backTo)  // Uses backTo — navigates to the correct route
    

    Here's the flow that triggers the bug:

    1. User opens the receipt modal (TransactionReceiptModalContent)
    2. User presses "Replace" — on native this calls Navigation.goBack() to dismiss the receipt modal, then via microtask queue navigates to MONEY_REQUEST_STEP_SCAN with backTo set to Navigation.getActiveRoute() (the receipt modal route)
    3. The scan screen opens in the RHP (MoneyRequestModalStackNavigator)
    4. User captures a photo → updateScanAndNavigate fires → calls navigateBack() → Navigation.goBack() without backTo

    Because goBack() is called without backTo, it simply pops the current screen from the navigation stack rather than using goUp(backTo) to navigate to the correct destination. This leaves the user in an incorrect navigation state where pressing back leads them back to the camera screen.

    On web, navigateBack() passes backTo to goBack(), which calls goUp(backTo) — this correctly resolves the target route and navigates there, avoiding the issue entirely.

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

    Update navigateBack() in src/pages/iou/request/step/IOURequestStepScan/index.native.tsx to pass backTo to Navigation.goBack(), matching the web behavior:

    // Before (line 80-82):
    const navigateBack = () => {
        Navigation.goBack();
    };
    
    // After:
    const navigateBack = () => {
        Navigation.goBack(backTo);
    };
    

    This ensures that after taking a replacement photo on native, the navigation correctly goes back to the route stored in backTo (the receipt modal route or the screen the user came from) rather than blindly popping one screen.

    The updateScanAndNavigate function (lines 254-272) already has a special case using backTo for when navigation state is lost, but the normal flow path should also use it.

    What alternative solutions did you explore? (Optional)

    An alternative would be to modify updateScanAndNavigate directly to always use Navigation.goBack(backTo) in its normal flow path (the else branch at line 267), rather than calling navigateBack(). However, since navigateBack is also used for the header back button press (onBackButtonPress={navigateBack} at line 448), fixing navigateBack itself ensures consistent behavior for both the photo capture flow and manual back button presses.

    Relevant Code References

    • src/pages/iou/request/step/IOURequestStepScan/index.native.tsx:80-82 — Native navigateBack missing backTo
    • src/pages/iou/request/step/IOURequestStepScan/index.tsx:89-91 — Web navigateBack correctly using backTo
    • src/pages/iou/request/step/IOURequestStepScan/index.native.tsx:254-272 — Native updateScanAndNavigate
    • src/pages/media/AttachmentModalScreen/routes/TransactionReceiptModalContent.tsx:510-533 — Replace button navigation (sets backTo)

    Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, or @MelvinBot <your feedback> to refine this analysis.

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

    @melvin-bot

    Current assignee @truph01 is eligible for the External assigner, not assigning anyone new.

  10. 15 remaining items

  11. melvin-bot commented on Apr 6, 2026

    @melvin-bot

    This issue has not been updated in over 15 days. @NicMendonca, @truph01 eroding to Monthly issue.

    P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do!

  12. removed their assignment
    on Apr 24, 2026
  13. dominictb commented on May 1, 2026

    @dominictb
    Contributor

    @truph01 Are you due payment here?

  14. truph01 commented on May 1, 2026

    @truph01
    Contributor

    @dominictb Yes, since I worked on this as C+.

  15. truph01 commented on May 1, 2026

    @truph01
    Contributor

    BugZero Checklist:

    • [Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.

      Link to the comment on the PR: https://github.com/Expensify/App/pull/32764/changes#r3172409680

    • [Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.

      Link to discussion:

    • [Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.

    • [BugZero Assignee] Create a GH issue for creating/updating the regression test once above steps have been agreed upon.

      Link to issue:

    Regression Test Proposal

    Precondition:

    Test:

    1. Create two expenses, one of which has a receipt.
    2. Tap Reports and select the expense that has the receipt.
    3. Tap on the receipt and the overflow button.
    4. Select Replace.
    5. Take a photo.
    6. Tap back or swipe to return to the previous screen.
    7. Verify the user navigates back to the correct screen (not the camera screen).

    Do we agree 👍 or 👎

    Zapier Logs Run ID: 00040eee-8dfb-a090-65d1-389d8ba010c4
  16. mallenexpensify commented on May 1, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor+: @truph01 due $250 via NewDot

  17. garrettmknight commented on May 10, 2026

    @garrettmknight
    Contributor

    $250 approved for @truph01

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

Metadata

Metadata

Assignees

Labels

BugSomething is broken. Auto assigns a BugZero manager.ExternalAdded to denote the issue can be worked on by a contributorMonthlyKSv2

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions