Skip to content

[Due for payment 2026-09-18] Expense - Background changes from Inbox to Profile after refreshing verify contact RHP #100765

Closed

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: 9.4.75-0
Reproducible in staging?: Yes
Reproducible in production?: N/A - new feature, doesn't exist in prod
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #100292
Email or phone of affected tester (no customers): josdjnodsjiosjoj@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Mac 26.5 / Chrome
App Component: Money Requests

Action Performed:

Precondition:

  • Account is unverified.
  1. Go to staging.new.expensify.com
  2. Go to workspace chat.
  3. Create an expense.
  4. Open the report.
  5. Click Add your number on add receipt modal.
  6. Click on the contact email.
  7. Refresh the page.

Expected Result:

Inbox will remain as the background after refreshing verify contact RHP.

Actual Result:

Background changes from Inbox to Profile after refreshing verify contact RHP.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7255410_1788983890883.1.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Svetlana Lazutkina
Bug ID: 7255410

Issue OwnerCurrent Issue Owner: @dmkt9

Activity

  1. applause-bot commented on Sep 9, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/548b6675253e69304754f6f5fe33b16397bcf9d31d3f487e4c559c35f5b22593

  2. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 9, 2026
  3. melvin-bot commented on Sep 9, 2026

    @melvin-bot

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

  4. github-actions commented on Sep 9, 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.
  5. melvin-bot commented on Sep 9, 2026

    @melvin-bot

    @roryabraham @dmkt9 you have been assigned to this deploy blocker because you reviewed the offending PR: #100292

  6. melvin-bot commented on Sep 9, 2026

    @melvin-bot

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

  7. MelvinBot commented on Sep 9, 2026

    @MelvinBot
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: #100292 - "Let the base path decide the contact methods RHP background" by @mukhrr (High confidence)
    Related Issues: #100260 (the bug #100292 was fixing)

    Recommendation: ROLL FORWARD

    #100292 removed DYNAMIC_CONTACT_METHODS from SETTINGS_TO_RHP but left the three sibling contact-method dynamic screens pinned to Settings > Profile, so the list screen now follows the base path while the details ("verify contact") screen still resolves Profile on a fresh load. The forward fix is deleting those three remaining lines from the same file, which is smaller and safer than a revert — a revert would restore the consistent-but-wrong Profile background and reintroduce #100260 plus the double-back-press bug.

    Assigned: @mukhrr (PR author), @roryabraham and @dmkt9 (approving reviewers) from highest-confidence causing PR only
    Labels: No changes. DeployBlockerCash is correct and stays (App-side fix, App deploy blocked). DeployBlocker was not present, so nothing removed.

    📋 Detailed Analysis

    Evidence

    Verification

    Affected file: src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts (the only file #100292 touched — confirmed via gh pr view 100292 --json files).

    The repro's "Add your number" link is built from the current screen's path, not a /settings/... path — ReceiptAlternativeMethods uses useScreenBoundDynamicRoute(DYNAMIC_ROUTES.CONTACT_METHODS.path) — so from an expense report opened in the wide RHP the URL is /e/<reportID>/contact-methods, then /e/<reportID>/contact-methods/<email>/details.

    I ran getAdaptedStateFromPath against those real URLs on current staging code and recorded which fullscreen ends up under the RHP:

    URL (browser refresh) Background resolved
    /e/456/contact-methods Home ✅ correct (fixed by #100292)
    /e/456/contact-methods/foo@gmail.com/details SettingsSplitNavigator → Settings_Profile ❌ the bug
    /search/r/456/contact-methods/…/details SettingsSplitNavigator → Settings_Profile ❌ same bug
    /e/456/contact-methods/new-contact-method SettingsSplitNavigator → Settings_Profile ❌ same latent bug
    /e/456/contact-methods/new/confirm-validate-code SettingsSplitNavigator → Settings_Profile ❌ same latent bug
    /e/456/contact-methods/verify-account Home ✅ correct (never listed in the relation map)

    Simulating the pre-#100292 map (re-adding DYNAMIC_CONTACT_METHODS) makes both the list and the details URL resolve Settings_Profile — consistent, and matching the pre-PR behaviour described in #100260. Simulating the proposed fix (dropping the three remaining entries) gives:

    URL Background resolved
    /e/456/contact-methods/foo@gmail.com/details Home ✅
    /search/r/456/contact-methods/foo@gmail.com/details SearchFullscreenNavigator → Search_Root ✅
    /r/123/contact-methods/foo@gmail.com/details ReportsSplitNavigator → Report ✅
    /settings/profile/contact-methods/foo@gmail.com/details SettingsSplitNavigator → Settings_Profile ✅ (still correct)

    Root Cause

    getMatchingFullScreenRoute resolves the fullscreen route to show under an RHP by checking the static *_TO_RHP relation maps first, and only falls back to "strip the dynamic suffix and let the base path decide" afterwards. A dynamic route can be appended to any base path — CONTACT_METHODS declares entryScreens: ['*'], and CONTACT_METHOD_DETAILS / NEW_CONTACT_METHOD / NEW_CONTACT_METHOD_CONFIRM_VALIDATE_CODE hang off it — so pinning them to a fixed central pane is always wrong.

    On a fresh load, getAdaptedState first tries getDynamicRouteAdaptedState, which walks the URL suffixes down to the base path. When the base path is itself an RHP route (/e/:reportID, the expense report in the wide RHP) that walk cannot produce a fullscreen, so it falls through to getMatchingFullScreenRoute — which hits the still-present RHP_TO_SETTINGS entry and injects Settings > Profile. In-app navigation to the same screen never consults that map (linkTo skips the fullscreen-matching block while an RHP is on top), which is why the background only jumps on refresh.

    Suggested fix — delete the three remaining lines so the base path decides, exactly as #100292 did for the list:

         [SCREENS.SETTINGS.PROFILE.ROOT]: [
             SCREENS.SETTINGS.PROFILE.DISPLAY_NAME,
             SCREENS.SETTINGS.PROFILE.AVATAR,
    -        SCREENS.SETTINGS.PROFILE.DYNAMIC_CONTACT_METHOD_DETAILS,
    -        SCREENS.SETTINGS.PROFILE.DYNAMIC_NEW_CONTACT_METHOD,
    -        SCREENS.SETTINGS.PROFILE.DYNAMIC_NEW_CONTACT_METHOD_CONFIRM_VALIDATE_CODE,
             SCREENS.SETTINGS.PROFILE.CONTACT_METHOD_SET_DEFAULT_CONFIRM,

    Worth a regression test asserting the resolved background for /e/:reportID/contact-methods/:contactMethod/details, since the in-app path and the deep-link path go through different code and only the deep-link one was broken.

    💡 Suggested AI code review rule

    This bug looks like a recurring, mechanically detectable pattern, so it may be worth a coding-standards rule so the AI reviewer catches the next one. Proposed for Expensify/App:

    • Rule: CONSISTENCY-18 Don't pin an "anywhere" dynamic route to a fullscreen in the *_TO_RHP relations
    • Condition: Flag adding a SCREENS.*.DYNAMIC_* screen to any src/libs/Navigation/linkingConfig/RELATIONS/*_TO_RHP.ts map when its DYNAMIC_ROUTES entry declares entryScreens: ['*'], or when its entryScreens are dynamic screens that themselves declare ['*']. Leave it out and let the base path decide.
    • Why: getMatchingFullScreenRoute checks the relation maps before the dynamic base-path branch, so a pinned dynamic screen resolves a fixed central pane on deep link / refresh while in-app navigation keeps the real base path — the background jumps on refresh (this issue).
    • Search pattern: grep -rn "DYNAMIC_" src/libs/Navigation/linkingConfig/RELATIONS/, then for each hit check its DYNAMIC_ROUTES entry in src/ROUTES.ts for entryScreens: ['*'] (directly or transitively). Five live hits today: the three contact-method screens plus DYNAMIC_EXIT_SURVEY_REASON / DYNAMIC_EXIT_SURVEY_CONFIRM, which are pinned to Settings > Troubleshoot despite EXIT_SURVEY_* declaring entryScreens: ['*'].
    • Offending code (❌): SETTINGS_TO_RHP.ts#L10-L12
    • Fix (✅): the existing precedent for deliberately leaving one out, WORKSPACE_TO_RHP.ts#L28-L32

    The full rule file, with the ❌/✅ code inline in App's coding-standards format, would go in Expensify/App itself. If it's worth adding, a maintainer can open it there as a draft PR.

  8. roryabraham commented on Sep 9, 2026

    @roryabraham
    Contributor

    demoting this

  9. 35 remaining items

  10. mallenexpensify commented on Sep 29, 2026

    @mallenexpensify
    Contributor

    @dmkt9 👀 above plz

  11. dmkt9 commented on Oct 1, 2026

    @dmkt9
    Contributor

    @dmkt9 👀 above plz

    @mallenexpensify Ah, yes. Sorry, I mixed this up with another issue. This issue is considered a follow-up, so no payment is due here.

  12. mukhrr commented on Oct 1, 2026

    @mukhrr
    Contributor

    @dmkt9 I don't agree.

    I clearly mentioned here why

    I mean the bug persisted with/without our change in #100292. and #100260 did't mention contact methods DETAILS path, I mean we found the bug with only contact methods path and were fixing it.

    So @mallenexpensify in short, #100292 fixed #100260 (which is 'Click the "Add your number" link in Expense details' case). But this issue expects "Click contact methods path" and we fixed this separately. cc @roryabraham

  13. mallenexpensify commented on Oct 2, 2026

    @mallenexpensify
    Contributor

    @roryabraham 👀 above when you're back plz, Thx

  14. roryabraham commented on Oct 5, 2026

    @roryabraham
    Contributor

    I think we agreed it's a separate issue, not a follow-up

  15. mallenexpensify commented on Oct 6, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor: @mukhrr due $250 via Upwork
    Contributor+: @dmkt9 paid $250 via NewDot

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

  16. dmkt9 commented on Oct 6, 2026

    @dmkt9
    Contributor

    @dmkt9 can you please accept the job below? Please reply here and tag me once you have.

    @mallenexpensify Thanks. I've accepted the offer

  17. mallenexpensify commented on Oct 6, 2026

    @mallenexpensify
    Contributor

    @dmkt9 paid, summary updated above. Thx.

  18. flaviadefaria commented on Oct 9, 2026

    @flaviadefaria
    Contributor

    Approved: @mukhrr due $250 via NewDot

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.DailyKSv2Engineering

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions