Skip to content

Expense - "Allow location access" modal shows up when creating manual expense with 0 amount #85158

Closed

Description

@mitarachim

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.37-0
Reproducible in staging?: Yes
Reproducible in production?: No
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #83354
Email or phone of affected tester (no customers): soidjsodijsodjnsoidjs@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Mac 26.2 / Chrome
App Component: Money Requests

Action Performed:

Precondition:

  • Location access is not allowed.
  1. Go to staging.new.expensify.com
  2. Create a new account.
  3. Create a workspace.
  4. Go to workspace chat.
  5. Click + > Create expense > Manual.
  6. Enter 0 > Next.
  7. On confirm page, enter Merchant.
  8. Click Create expense.

Expected Result:

"Allow location access" modal will not show up because the expense is a manual expense.

Actual Result:

"Allow location access" modal shows up when creating manual expense with 0 amount.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7101662_1773359553305.4.mp4

View all open jobs on GitHub

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    DeployBlockerIndicates it should block deploying the API
    on Mar 13, 2026
  2. melvin-bot commented on Mar 13, 2026

    @melvin-bot

    You have been assigned to this deploy blocker because you recently merged this PR: #83354

  3. melvin-bot commented on Mar 13, 2026

    @melvin-bot

    💬 A slack conversation has been started in #expensify-open-source

  4. OSBotify commented on Mar 13, 2026

    @OSBotify
    Contributor

    Investigation Summary

    Classification: Frontend bug
    Causing PR: #83354 - "Pass locationPermissionGranted=true when permission was already grant..." by @MobileMage (High confidence)
    Related Issues: #81184 (original issue that PR 83354 was fixing)

    Recommendation: REVERT

    PR #83354 should be reverted. While it successfully fixed the original issue (scanned receipts not collecting GPS for currency detection), it introduced a regression where manual expenses with 0 amount now incorrectly trigger the location permission modal.

    Labels: Keeping DeployBlockerCash - this is an App bug that requires reverting an App PR. Removing DeployBlocker as this is not a backend issue.

    Detailed Analysis

    Evidence

    PR #83354 modified src/pages/iou/request/step/IOURequestStepScan/useReceiptScan.ts to pass locationPermissionGranted=true when:

    1. shouldSkipConfirmation is true
    2. gpsRequired is true (amount === 0)
    3. Permission was already granted

    The problem is in the gpsRequired condition:

    const gpsRequired = initialTransaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && files.length;

    This condition checks for 0 amount expenses but does NOT distinguish between:

    • Scanned receipts (which need GPS to determine currency from location)
    • Manual expenses (which do not need GPS)

    Verification

    From the issue reproduction steps:

    1. Create a manual expense (not scanned)
    2. Enter amount 0
    3. The location permission modal incorrectly appears

    The fix applies to lines 234-246 in processReceipts() and lines 254-263 in submitReceipts() in useReceiptScan.ts, where the GPS requirement logic does not check the expense type.

    Root Cause

    The PR correctly identified that scanned receipts with 0 amount need GPS coordinates for currency detection when permission is already granted. However, the implementation applies this logic to ALL expenses with 0 amount, including manual expenses that should never trigger location permission flows.

    The same issue exists in IOURequestStepConfirmation.tsx line 285:

    const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && Object.values(receiptFiles).length && !isTestTransaction;

    This condition should additionally check if the expense is a scanned receipt (e.g., using isScanRequest(transaction)) before requiring GPS.

  5. github-actions commented on Mar 13, 2026

    @github-actions
    Contributor

    👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

    1. Identify the pull request that introduced this issue and revert it.
    2. Find someone who can quickly fix the issue.
    3. Fix the issue yourself.
  6. MobileMage commented on Mar 13, 2026

    @MobileMage
    Contributor

    Looking into this

  7. MelvinBot commented on Mar 13, 2026

    @MelvinBot
    Contributor

    Proposal

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

    When creating a manual expense with 0 amount (+ > Create expense > Manual > Enter 0 > Next > Confirm), the "Allow location access" modal incorrectly appears. This modal should only appear for scanned receipts that need GPS coordinates to determine currency from location — never for manual expenses.

    What is the root cause of that problem?

    The gpsRequired condition in IOURequestStepConfirmation.tsx:285 uses transaction.amount === 0 as a proxy for "this is a scanned receipt needing GPS," but manual expenses can also have amount=0:

    const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && Object.values(receiptFiles).length && !isTestTransaction;
    

    The condition relies on Object.values(receiptFiles).length being truthy to filter out non-receipt expenses. However, setMoneyRequestAmount() in IOU/index.ts:1440-1442 always calls setMoneyRequestReceiptState(), which merges {receipt: {state: 'OPEN'}} into the transaction draft — even for manual expenses. The useEffect at line 521 of IOURequestStepConfirmation.tsx then picks up this phantom receipt and populates receiptFiles, making the length check truthy.

    So for a manual expense with amount=0: amount === 0 is true, receiptFiles.length is truthy (due to the phantom receipt), and gpsRequired evaluates to truthy, incorrectly triggering the LocationPermissionModal at line 1577.

    Note: The existing analysis suggested PR #83354 introduced this, but PR #83354 only modified useReceiptScan.ts (the scan flow). Manual expenses never go through useReceiptScan — they go through IOURequestStepAmount → IOURequestStepConfirmation. The bug in the confirmation page's gpsRequired logic is independent of that PR and was likely discovered during its regression testing.

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

    Add an isScanRequest(transaction) check to the gpsRequired condition in IOURequestStepConfirmation.tsx:285. The isScanRequest function is already imported (line 82) and correctly returns false for manual expenses by checking transaction.iouRequestType === CONST.IOU.REQUEST_TYPE.SCAN:

    const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && isScanRequest(transaction) && Object.values(receiptFiles).length && !isTestTransaction;
    

    This is a targeted one-line fix that preserves the GPS behavior for actual scanned receipts while preventing the location modal from appearing for manual expenses.

    What alternative solutions did you explore? (Optional)

    1. Reverting PR Pass locationPermissionGranted=true when permission was already grant… #83354: As suggested by the existing analysis. However, since PR Pass locationPermissionGranted=true when permission was already grant… #83354 didn't introduce this specific bug (it only changed the scan flow in useReceiptScan.ts), a revert would undo the legitimate fix from [$250] Expense- Receipt scan without currency assigns incorrect currency based on location #81184 without actually fixing this issue.

    2. Fixing setMoneyRequestReceiptState: Preventing it from setting phantom receipt state on manual expenses would also fix this, but that function is called from multiple places (setMoneyRequestAmount, setMoneyRequestCreated, etc.) and may have other consumers that rely on the behavior. The isScanRequest guard on gpsRequired is a safer, more targeted fix.


    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.

  8. MobileMage commented on Mar 13, 2026

    @MobileMage
    Contributor

    Proposal

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

    When creating a manual expense with 0 amount, the "Allow location access" modal incorrectly appears. This should only happen for scanned receipt expenses where GPS is needed to determine currency from location.

    What is the root cause of that problem?

    The gpsRequired condition in IOURequestStepConfirmation.tsx (line 285) uses transaction?.amount === 0 as a proxy for "this is a scanned receipt." But manual expenses can also have 0 amount, and the condition doesn't verify the request type:

    const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && Object.values(receiptFiles).length && !isTestTransaction;
    

    This means any 0-amount expense that happens to have receipt files will trigger the location permission flow, even if it's not a scan request.

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

    Add isScanRequest(transaction) to the gpsRequired condition in IOURequestStepConfirmation.tsx. This function checks transaction.iouRequestType === CONST.IOU.REQUEST_TYPE.SCAN, ensuring the location modal only appears for actual scan requests. It's already imported in the file.

    What alternative solutions did you explore? (Optional)

    Reverting PR #83354 was considered, but that would re-introduce the original issue (#81184) where scanned receipts weren't collecting GPS for currency detection. The targeted fix preserves that behavior while preventing the regression for manual expenses.

  9. Valforte commented on Mar 13, 2026

    @Valforte
    Contributor

    @MobileMage for timeliness, I'll revert the original PR, can you recreate your PR with the proposed fix?

  10. MobileMage commented on Mar 13, 2026

    @MobileMage
    Contributor
  11. Valforte commented on Mar 13, 2026

    @Valforte
    Contributor

    I actually changed my mind and applied your suggested fix, PR is #85261

  12. MobileMage commented on Mar 13, 2026

    @MobileMage
    Contributor

    Oh okay, great!

  13. IuliiaHerets commented on Mar 13, 2026

    @IuliiaHerets

    Chrome / v9.3.37-7
    Not reproduce

    Screen.Recording.2026-03-13.at.21.19.18.mp4
  14. luacmartins commented on Mar 13, 2026

    @luacmartins
    Contributor

    Fixed. Closing.

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.EngineeringHourlyKSv2ReviewingHas a PR in review

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions