You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-10-27] Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge #99940
Version Number: v9.4.64-2 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/13176964/test-cases/41237739 Email or phone of affected tester (no customers):[email protected] Issue reported by: Applause Internal Team Bug source: Regression TC Execution Device used: Windows 10/Chrome App Component: Other
The /concierge deeplink is captured correctly, then deliberately thrown away because the account had not finished onboarding when the link was captured.
openReportFromDeepLink parks the pending route behind sign-in, latching whether onboarding was already complete at capture time (src/libs/actions/Link.ts:562). For a brand-new sign-up that value is false, and when the deeplink finally replays it hits an unconditional early return (src/libs/actions/Link.ts:600-604):
// Drop a deep link captured before onboarding finished: navigateAfterOnboarding owns the// post-onboarding destination and overrides it anyway, so honoring it only risks the flash (#91437).if(initialHasCompletedGuidedSetupFlow===false){return;}
That comment's premise is wrong. navigateAfterOnboarding has no access to the deeplink — with no admins chat on a wide screen it goes straight to ROUTES.HOME (src/libs/navigateAfterOnboarding.ts:109-114). So nothing "overrides" the destination; it is simply lost, and because the guard sits after Onyx.disconnect(connection) (Link.ts:582) there is no retry.
This is why existing accounts work: their latched value is true, so the guard is skipped and Navigation.navigate('concierge') fires (Link.ts:628).
The guard was added by #92839 (merged 2026-06-25) to fix the post-onboarding "Not here" flash in #91437.
Note this is not specific to Concierge — any deeplink captured before a fresh sign-up is dropped the same way. ConciergePage itself is fine; it correctly waits on onServerDataReady() and creates the DM when conciergeReportID is missing (ConciergePage.tsx:35-49). It is simply never mounted.
What changes do you think we should make in order to solve the problem?
Stop discarding the pending route and instead hand it to the code that owns the post-onboarding destination, which is what the comment already assumes happens.
Replace the blanket return at Link.ts:600-604 with a persisted "pending post-onboarding route" (a new Onyx key), rather than dropping the route.
Also revisit the earlier drop at Link.ts:587-590. On web this branch fires first, because the replay gate opens on completeOnboarding's optimistic NVP merge while the onboarding modal is still focused (dismissOnboardingModalBeforeExit is a no-op on web). It currently discards the link and sets a spurious onboarding.purpose.errorBackButton message. It should persist the pending route too.
Because SCREENS.CONCIERGE is in MODAL_ROUTES_TO_DISMISS (GetStateForActionHandlers.ts:56), the replay must happen after onboarding tears down its modal, not during it — otherwise RootStackRouter strips the route out of the stack again.
What alternative solutions did you explore? (Optional)
Narrow the guard to an allow-list (let ROUTES.CONCIERGE through). Smaller change, but it only fixes Concierge and leaves every other deeplink broken for new users.
Investigation details, alternatives ruled out, and test evidence
Ordered path for a new sign-up (verified against d178dd2):
Signed out at /concierge → DeepLinkHandler reads Linking.getInitialURL() with hasAuthToken() === false and calls openReportFromDeepLink(..., isAuthenticated=false).
route = 'concierge'; reportID is empty (not an /r/ link) and concierge is not in PUBLIC_SCREENS_ROUTES, so it survives the early bail-outs and parks in waitForUserSignIn() (Link.ts:525). A JS closure, not the URL or navigation state, is the sole carrier.
Sign-up completes → NVP_ONBOARDING arrives as {hasCompletedGuidedSetupFlow: false} → latched at Link.ts:562, and the replay gate at Link.ts:648 stays shut for the whole onboarding flow.
Onboarding finishes → optimistic merge flips the NVP to true → gate opens → handleDeeplinkNavigation() disconnects, then returns at :587 (web) or :602. Link destroyed, no retry.
navigateAfterOnboarding → Navigation.navigate(ROUTES.HOME). Home rendered.
Ruled out with evidence: a CONCIERGE_REPORT_ID load race (ConciergePage handles the missing ID and retries via its focus effect); NavigationRoot.initialState (bails at !account on a signed-out cold start and has [] deps, so it never recomputes after sign-in); LAST_VISITED_PATH (only consumed when already authenticated on first render); AuthScreensInitHandler and setUpPoliciesAndNavigate (both no-op — the former only handles /r/<reportID> links, the latter requires an exitTo param).
Remaining uncertainty (does not change the root cause): whether the backend ever returns an empty nvp_onboarding before {hasCompletedGuidedSetupFlow: false}. If it does, hasCompletedGuidedSetupFlowSelector({}) returns true, the navigate does fire, and the loss shifts to the OnboardingGuard redirect + RootStackRouter stack rebuild instead. Both paths end on Home, and the fix above covers both.
Test evidence: a web tester run could not exercise this flow. The already-authenticated CI session has no way to perform a cold URL load or reload (both are disallowed for that session, since a reload can drop client auth into an unclearable magic-code wall), and clicking through the LHN would only exercise client-side routing, not a deeplink. The analysis above rests on code reading, not a live repro.
Step
Status
Observation
Session reaches Home before driving task
pass
Home/Inbox/Spend/Workspaces tabs and Concierge composer visible after dismissing the welcome screen
Navigate browser directly to /concierge URL
fail
No permitted agent-device verb performs a cold URL navigation for this session
Reload while on /concierge and observe landing screen
fail
Reload disallowed — risks dropping client auth
Evidence (1)
App at Home after completing prestart setup
Possibly related (different flow, same theme of a post-sign-in destination being lost):#96346 and #95445, both about public rooms not opening after an anonymous user signs in. Neither passes through the initialHasCompletedGuidedSetupFlow guard, so I do not think they share this root cause.
Next Steps for Contributor+ team: To accept:@MelvinBot implement this proposal to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
changed the title [-][Due for payment 2026-10-12] Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/-][+]Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/+]on Oct 14, 2026
changed the title [-]Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/-][+][Due for payment 2026-10-27] Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/+]on Oct 20, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.14-3 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-10-27. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ 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]. If no checklist is needed for this issue, you can click: [no checklist button]
Activity
applause-bot commentedon Aug 31, 2026
While Applause doesn't embed attachments for this bug, here are the links for quick view:
https://platform.applause.com/services/links/v1/external/8ce52a25149947e58bca9b78606f07b7cae5abd202fcd2fa02af96f7578852fa
MelvinBot commentedon Aug 31, 2026
Proposal
What is the root cause of that problem?
The
/conciergedeeplink is captured correctly, then deliberately thrown away because the account had not finished onboarding when the link was captured.openReportFromDeepLinkparks the pending route behind sign-in, latching whether onboarding was already complete at capture time (src/libs/actions/Link.ts:562). For a brand-new sign-up that value isfalse, and when the deeplink finally replays it hits an unconditional early return (src/libs/actions/Link.ts:600-604):That comment's premise is wrong.
navigateAfterOnboardinghas no access to the deeplink — with no admins chat on a wide screen it goes straight toROUTES.HOME(src/libs/navigateAfterOnboarding.ts:109-114). So nothing "overrides" the destination; it is simply lost, and because the guard sits afterOnyx.disconnect(connection)(Link.ts:582) there is no retry.This is why existing accounts work: their latched value is
true, so the guard is skipped andNavigation.navigate('concierge')fires (Link.ts:628).The guard was added by #92839 (merged 2026-06-25) to fix the post-onboarding "Not here" flash in #91437.
Note this is not specific to Concierge — any deeplink captured before a fresh sign-up is dropped the same way.
ConciergePageitself is fine; it correctly waits ononServerDataReady()and creates the DM whenconciergeReportIDis missing (ConciergePage.tsx:35-49). It is simply never mounted.What changes do you think we should make in order to solve the problem?
Stop discarding the pending route and instead hand it to the code that owns the post-onboarding destination, which is what the comment already assumes happens.
returnatLink.ts:600-604with a persisted "pending post-onboarding route" (a new Onyx key), rather than dropping the route.navigateAfterOnboarding, prefer that pending route overROUTES.HOME/the admins room when one is set, then clear the key. Because the navigation now happens after onboarding completes rather than during it, the [Due for payment 2026-07-03] [$250] Onboarding - Not here page appears briefly after completing onboarding #91437 flash does not return.Link.ts:587-590. On web this branch fires first, because the replay gate opens oncompleteOnboarding's optimistic NVP merge while the onboarding modal is still focused (dismissOnboardingModalBeforeExitis a no-op on web). It currently discards the link and sets a spuriousonboarding.purpose.errorBackButtonmessage. It should persist the pending route too.Because
SCREENS.CONCIERGEis inMODAL_ROUTES_TO_DISMISS(GetStateForActionHandlers.ts:56), the replay must happen after onboarding tears down its modal, not during it — otherwiseRootStackRouterstrips the route out of the stack again.What alternative solutions did you explore? (Optional)
ROUTES.CONCIERGEthrough). Smaller change, but it only fixes Concierge and leaves every other deeplink broken for new users.Investigation details, alternatives ruled out, and test evidence
Ordered path for a new sign-up (verified against
d178dd2):/concierge→DeepLinkHandlerreadsLinking.getInitialURL()withhasAuthToken() === falseand callsopenReportFromDeepLink(..., isAuthenticated=false).route = 'concierge';reportIDis empty (not an/r/link) andconciergeis not inPUBLIC_SCREENS_ROUTES, so it survives the early bail-outs and parks inwaitForUserSignIn()(Link.ts:525). A JS closure, not the URL or navigation state, is the sole carrier.NVP_ONBOARDINGarrives as{hasCompletedGuidedSetupFlow: false}→ latched atLink.ts:562, and the replay gate atLink.ts:648stays shut for the whole onboarding flow.true→ gate opens →handleDeeplinkNavigation()disconnects, then returns at:587(web) or:602. Link destroyed, no retry.navigateAfterOnboarding→Navigation.navigate(ROUTES.HOME). Home rendered.Ruled out with evidence: a
CONCIERGE_REPORT_IDload race (ConciergePagehandles the missing ID and retries via its focus effect);NavigationRoot.initialState(bails at!accounton a signed-out cold start and has[]deps, so it never recomputes after sign-in);LAST_VISITED_PATH(only consumed when already authenticated on first render);AuthScreensInitHandlerandsetUpPoliciesAndNavigate(both no-op — the former only handles/r/<reportID>links, the latter requires anexitToparam).Remaining uncertainty (does not change the root cause): whether the backend ever returns an empty
nvp_onboardingbefore{hasCompletedGuidedSetupFlow: false}. If it does,hasCompletedGuidedSetupFlowSelector({})returnstrue, the navigate does fire, and the loss shifts to theOnboardingGuardredirect +RootStackRouterstack rebuild instead. Both paths end on Home, and the fix above covers both.Test evidence: a web tester run could not exercise this flow. The already-authenticated CI session has no way to perform a cold URL load or reload (both are disallowed for that session, since a reload can drop client auth into an unclearable magic-code wall), and clicking through the LHN would only exercise client-side routing, not a deeplink. The analysis above rests on code reading, not a live repro.
/conciergeURL/conciergeand observe landing screenEvidence (1)
App at Home after completing prestart setup
Possibly related (different flow, same theme of a post-sign-in destination being lost): #96346 and #95445, both about public rooms not opening after an anonymous user signs in. Neither passes through the
initialHasCompletedGuidedSetupFlowguard, so I do not think they share this root cause.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement this proposalto create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run
melvin-bot commentedon Aug 31, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @eh2077 (
External)melvin-bot commentedon Aug 31, 2026
Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.
melvin-bot commentedon Sep 3, 2026
@eh2077 Whoops! This issue is 2 days overdue. Let's get this updated quick!
melvin-bot commentedon Sep 4, 2026
@eh2077 Whoops! This issue is 2 days overdue. Let's get this updated quick!
melvin-bot commentedon Sep 4, 2026
@eh2077 Whoops! This issue is 2 days overdue. Let's get this updated quick!
eh2077 commentedon Sep 4, 2026
checking
68 remaining items
melvin-bot commentedon Oct 11, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Oct 11, 2026
Payment Summary
Resolving PRs:
Open a deep link captured before onboarding instead of dropping it #101558
Reviewer: @mukhrr owed $175 via NewDot
Reviewer: @eh2077 owed $175 via NewDot
BugZero Checklist (@mallenexpensify)
mukhrr commentedon Oct 11, 2026
This is not due payment yet. We are working on regression PR
[-][Due for payment 2026-10-12] Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/-][+]Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/+]mallenexpensify commentedon Oct 14, 2026
Please comment and tag me if/when payment is due, thx
jponikarchuk commentedon Oct 19, 2026
Deploy Blocker #104391 was identified to be related to the PR #103681 that attempted to fix this issue.
melvin-bot commentedon Oct 19, 2026
If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.
If a regression has occurred and you are the assigned CM follow the instructions here.
If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.
[-]Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/-][+][Due for payment 2026-10-27] Deeplink - New user is not navigated to Concierge chat after deeplinking to Concierge[/+]melvin-bot commentedon Oct 20, 2026
@eh2077
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.14-3 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-10-27. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ 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]. If no checklist is needed for this issue, you can click: [no checklist button]
melvin-bot commentedon Oct 21, 2026
@eh2077 Still overdue 6 days?! Let's take care of this!
melvin-bot commentedon Oct 23, 2026
@eh2077 8 days overdue is a lot. Should this be a Weekly issue? If so, feel free to change it!