Skip to content

[Due for payment 2026-05-07] [$500] Expense - Map expense is shown instead scan expense. #86248

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.43-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: #85589
Email or phone of affected tester (no customers): dreamnitethedragon+yydyd373@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Redminote 10S Android 13
App Component: Money Requests

Action Performed:

  1. Launch app
  2. Login with new gmail account
  3. Create workspace
  4. Create a room - invite a user sending message @dreamnitethedragon+cr6ytui@gmail.com ( from whisper select invite to chat)
  5. Create a split distance map expense in room created
  6. Tap multiple receipt scanning icon
  7. Take 2 camera image and proceed
  8. Create expense

Expected Result:

Scan expense must be shown.

Actual Result:

Map expense is shown instead scan expense.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Video.mp4

View all open jobs on GitHub

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

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    and removed on Apr 14, 2026
  2. MelvinBot commented on Apr 14, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    When submitting a split expense in IOURequestStepConfirmation.tsx:999, the distance request check runs before the scan receipt check at line 1007:

    Line 999:  if (iouType !== TRACK && isDistanceRequest && ...) { createDistanceRequest(...); return; }
    Line 1007: if (iouType === SPLIT && receiptFiles.length) { startSplitBill(...); return; }
    

    If the draft transaction retains iouRequestType: 'distance' when the user switches to the scan tab, isDistanceRequest returns true and a distance expense is created — even though the user captured receipt photos.

    The draft retains the stale type because of a guard in IOURequestStartPage.tsx:233-248: the useFocusEffect skips calling resetIOUTypeIfChanged when transaction?.reportID === reportID. After completing a split distance expense and immediately starting a new split from the same room, the old draft (with iouRequestType: 'distance') may still be present because cleanup is deferred via InteractionManager.runAfterInteractions. If the OnyxTabNavigator also doesn't fire onTabSelected (because the persisted tab already matches), resetIOUTypeIfChanged is never called, and the draft keeps iouRequestType: 'distance'.

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

    The distance check at line 999 should not take priority when the user has receipt files. Add a receipt-file guard to the distance check condition:

    At IOURequestStepConfirmation.tsx:999, add a check that there are no receipt files before entering the distance path:

    if (iouType !== TRACK && isDistanceRequest && !isMovingTransactionFromTrackExpense && !isUnreported && !hasReceiptFiles) { ... }
    

    Where hasReceiptFiles is Object.values(receiptFiles).some(Boolean). This ensures that when the user has captured receipt photos, the flow falls through to the scan/split receipt path at line 1007 instead of creating a distance expense.

    What alternative solutions did you explore? (Optional)

    An alternative is to fix the useFocusEffect guard in IOURequestStartPage.tsx to always call resetIOUTypeIfChanged when the transaction type doesn't match the selected tab, regardless of whether the reportID matches. However, this is riskier since that guard exists to avoid resetting the transaction for other legitimate reasons (e.g., test transactions). The confirmation-level fix is more defensive and directly prevents the symptom.

    Supporting evidence

    Control flow in the submit handler (IOURequestStepConfirmation.tsx):

    1. Line 999: Distance check → createDistanceRequest and return
    2. Line 1007: Split with receipts → startSplitBill and return
    3. Line 1048: Split from room → splitBill and return

    The distance check at step 1 preempts the receipt check at step 2.

    Draft cleanup race condition (IOU/Split.ts:266): After splitBill completes, draft cleanup is deferred via InteractionManager.runAfterInteractions(() => removeDraftTransaction(...)). If the user starts a new split before this fires, the old draft persists.

    Tab navigator skip (OnyxTabNavigator.tsx:195-202): When the persisted tab in Onyx matches the current tab, onTabSelected is not called on mount, so resetIOUTypeIfChanged doesn't fire.

    useFocusEffect guard (IOURequestStartPage.tsx:237): transaction?.reportID === reportID causes early return when starting a new split from the same room — preventing re-initialization.


    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.

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

    @melvin-bot

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

  6. changed the title [-]Expense - Map expense is shown instead scan expense.[/-] [+][$250] Expense - Map expense is shown instead scan expense.[/+] on Apr 14, 2026
  7. 49 remaining items

  8. changed the title [-][Due for payment 2026-05-07] [$250] Expense - Map expense is shown instead scan expense.[/-] [+][Due for payment 2026-05-07] [$500] Expense - Map expense is shown instead scan expense.[/+] on May 5, 2026
  9. melvin-bot commented on May 5, 2026

    @melvin-bot

    Upwork job price has been updated to $500

  10. melvin-bot commented on May 6, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  11. ZhenjaHorbach commented on May 7, 2026

    @ZhenjaHorbach
    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.

    Unfortunately, I did not find a suitable PR

    • [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: NA

    • [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.

    Regression Test Proposal

    Test:

    1. Open App
    2. Create workspace
    3. Go to Track Distance > Map > enter waypoints > Next
    4. Kill the app
    5. Long press the app icon to access the “3D touch” menu > scan receipt
    6. Snap a picture of a receipt
    7. Verify that the Scan expense is shown.

    1. Open App
    2. Create workspace
    3. Create a room - invite a user sending message @dreamnitethedragon+cr6ytui@gmail.com ( from whisper select invite to chat)
    4. Create a split distance map expense in room created
    5. Tap multiple receipt scanning icon
    6. Take 2 camera image and proceed
    7. Create expense
    8. Verify that the Scan expense is shown.

    Do we agree 👍 or 👎

    Zapier Logs Run ID: 00040eee-7130-a2ac-4c91-8d7a5c693c94
  12. melvin-bot commented on May 7, 2026

    @melvin-bot

    Payment Summary

    Upwork Job

    BugZero Checklist (@mallenexpensify)

    • (if NewFeature) I have created a PR for any necessary HelpDot updates, or I confirmed no updates are necessary.
    • I have verified the correct assignees and roles are listed above and updated the necessary manual offers
    • I have verified that there are no duplicate or incorrect contracts on Upwork for this job (https://www.upwork.com/ab/applicants/2044069303414836894/hired)
    • I have verified the PR was not reverted
    • I have applied any discounts due to bugs/regressions introduced by this PR
    • I have paid out the Upwork contracts or cancelled the ones that are incorrect
    • I have verified the payment summary above is correct
  13. mallenexpensify commented on May 8, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor: @TaduJR paid $500 via Upwork
    Contributor+: @ZhenjaHorbach due $500 via NewDot

    @TaduJR can you please accept the job below? Please reply here and tag me once you have.
    https://www.upwork.com/jobs/~022044069303414836894

    ^ Test case created

  14. TaduJR commented on May 8, 2026

    @TaduJR
    Contributor

    Offer Accepted @mallenexpensify

    Thanks!

  15. mallenexpensify commented on May 8, 2026

    @mallenexpensify
    Contributor

    @TaduJR paid, summary updated above. Thx.

  16. garrettmknight commented on May 10, 2026

    @garrettmknight
    Contributor

    $500 approved for @ZhenjaHorbach

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