Repository navigation
Description
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.81-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/test-runs/74212640/folder/13176721/41236968/1766200870?sort=%2Bstatus_id
Email or phone of affected tester (no customers): gocemate+buzz19953@gmail.com
Issue reported by: Applause Internal Team
Bug source: Regression TC Execution
Device used: samsung galaxy a34 5g/16
App Component: Other
Action Performed:
Preconditions:
The Expensify app is installed
User is not signed in
Scenario 1:
- Select a photo from device gallery
- Share it to Expensify app
- Verify the login screen for Expensify app displayed
- Login with new user with private domain
Scenario 2:
- Select a photo from device gallery
- Share it to Expensify app
- Verify the login screen for Expensify app displayed
- Login with new user with public domain
Expected Result:
After signing you are redirected to the sharing flow
Actual Result:
Scenario 1: App freezes on sharing page
Scenario 2: After signing in share modal appears and disappears when onboarding modal show up. Also, there is a error messages on onboarding modal
Workaround:
Unknown
Platforms:
- Android: App
- Android: mWeb Chrome
- iOS: App
- iOS: mWeb Safari
- iOS: mWeb Chrome
- Windows: Chrome
- MacOS: Chrome Safari
Screenshots/Videos
Bug7261874_1789592511813.Recording__1641.mp4
Bug7261874_1789634712783.ScreenRecording_09-16-2026_23-52-51_1.mp4
Applause Internal Information
Exported by: Svetlana Lazutkina
Bug ID: 7261874
Issue Owner
Current Issue Owner: @abbasifaizan70Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~022108292945299052480
- Upwork Job ID: 2108292945299052480
- Last Price Increase: 2026-10-08
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
applause-bot commentedon Sep 17, 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/6206f76e5be76d4d949b1f10c2dc5772d019fa70faa669870ebdcf893dde4aba
https://platform.applause.com/services/links/v1/external/2ebe0bc8f96f524359e8209034e7dcf780825d61b858502bc06a4907afea2b45
MelvinBot commentedon Sep 17, 2026
Proposal
What is the root cause of that problem?
The Android share intent is delivered as a plain deep link (
new-expensify://share/root) with no session or onboarding awareness (FileIntentHandler.kt:36-41). When the user is signed out, that route does not exist yet (SHARE_MODAL_NAVIGATORis only registered inAuthScreens), so the deep link is parked and replayed after sign-in byopenReportFromDeepLink. For a brand new user, three separate things then break it:Link.ts:613-617returns early wheneverhasCompletedGuidedSetupFlowwasfalseat sign-in, on the assumption thatnavigateAfterOnboardingowns the destination. ButnavigateAfterOnboardingonly knows about reports and Home — it has no notion of a pending share, so the shared file is abandoned. That is the "no sharing flow" half.NAVIGATORS.SHARE_MODAL_NAVIGATORis listed inMODAL_ROUTES_TO_DISMISS, andRootStackRouter.ts:136-160slices the stack at the first such route wheneverOnboardingGuardissues a redirect. The share flow is deleted, not stacked — "share modal appears and disappears".Link.ts:599-603setsonboarding.purpose.errorBackButton("Please finish the setup questions to start using the app") when the replayed link resolves while an onboarding screen is focused. A public-domain (gmail) user lands onOnboardingWorkEmail, whose Android back handler sets the same error — private-domain users land on a screen that swallows back silently, which is why only Scenario 2 shows errors.Why Scenario 1 (private domain) freezes instead: the onboarding navigator is registered as a transparent,
gestureEnabled: falsemodal (AuthScreens.tsx:352-363) and rendersnullwhile account metadata loads (OnboardingModalNavigator.tsx:109-112). The share page stays visible underneath but every touch goes to the empty focused screen on top — an apparent freeze, not a crash.What changes do you think we should make in order to solve the problem?
ROUTES.SHARE_ROOTfrom the early return atLink.ts:613-617, and instead persist it as a pending destination thatnavigateAfterOnboardingconsumes once guided setup finishes. This keeps the anti-flash behaviour that early return was added for while making the share flow survive onboarding.Link.ts:599-603, don't callsetOnboardingErrorMessagewhen the deep link is a share intent — the user never pressed back, so "Please finish the setup questions" is wrong.ShareRootPagefail loudly instead of hanging. Wrap theJSON.parse(processedFiles)atShareRootPage.tsx:103in a guard and set an error state. The native module invokes the callback with the bare string"No data found"when the prefs are empty (ShareActionHandlerModule.kt:32), which throws inside the callback, soisFileReadynever flips and the page rendersTabNavigatorSkeletonforever with no retry.Share_RoottoEXCLUDE_FROM_LAST_VISITED_PATH(runtimeDefaults.ts:92-109)./share/rootis currently persisted and restored on a later cold start, where there is no share payload at all — restoration is skipped for public-domain accounts (NavigationRoot.tsx:163-165), which is a second way private-domain users specifically reach a permanently skeletal share page.What alternative solutions did you explore? (Optional)
Alternatives considered and evidence
Alternative: defer onboarding while a share intent is pending. There is no such guard today —
startOnboardingFlowdeliberately bypasses the router with a rawnavigationRef.resetRoot(OnboardingFlow.ts:91-108, called fromuseOnboardingFlow.ts:135-139) precisely becauseOnboardingGuardwould block a normal navigate. Letting share pre-empt onboarding would mean a new user could post an attachment before having an account set up, so resuming after onboarding (fix 1) is safer.Alternative: gate the native intent on session state. The native handler could check for an auth token before firing the deep link and show a "sign in first" screen. This duplicates session logic in Kotlin and still needs the JS-side resume, so it doesn't remove any of the work above.
Ruled out: a native ANR / main-thread stall. The reported symptom is a freeze on the Expensify sharing page, i.e. JS already rendered the share screen, so the intent handling and file copy completed.
Timing note. The share modal is visible at all in Scenario 2 because
OnboardingGuardallows navigation whileONYXKEYS.IS_LOADING_APPis true; onceOpenAppreturns, the reset/redirect above tears it down. Exactly which of the two teardown paths wins is a race, so the ordering (but not the mechanism) is unconfirmed.Not verified: the report is build 9.4.81-0 on a Samsung device, which is likely HybridApp. All the JS fixes above are in this repo, but if HybridApp ships its own
MainActivity/manifest fromMobile-Expensify, the native half of the intent path should be re-checked there. I could not inspect that repo.Possibly related issues
Link.ts:613-617dropping a deep link for new users.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/101425)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run
melvin-bot commentedon Sep 17, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @jayeshmangwani (
External)melvin-bot commentedon Sep 17, 2026
Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.
melvin-bot commentedon Sep 22, 2026
@jayeshmangwani Huh... This is 4 days overdue. Who can take care of this?
melvin-bot commentedon Sep 24, 2026
@jayeshmangwani Still overdue 6 days?! Let's take care of this!
jayeshmangwani commentedon Sep 25, 2026
Melvin, let’s raise a draft PR so I can test the changes on my side and see how they work.
jayeshmangwani commentedon Sep 25, 2026
@MelvinBot implement this
69 remaining items
melvin-bot commentedon Oct 28, 2026
📣 @abbasifaizan70 You have been assigned to this job!
Please apply to the Upwork job and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑💻
Once you apply to this job, your Upwork ID will be stored and you will be automatically hired for future jobs!
Keep in mind: Code of Conduct | Contributing 📖
FitseTLT commentedon Oct 28, 2026
@jayeshmangwani @Gonals Thanks for the review. I'd like you to reconsider, because my proposal isn't a workaround. It extends a mechanism we already have for this exact situation.
This isn't a new behaviour. Opening a destination the user chose before signing up, once onboarding finishes, is something the app already does for public rooms. That was fixed in #92834 (issue #85242). We keep the deep-linked page in the stack underneath the onboarding redirect, so onboarding shows first and the user lands back on it afterwards:
[fullscreen, onboarding modal]instead of dropping what the user opened.Root cause. The share fails because this same setup doesn't account for a share:
navigateAfterOnboardingthen pushes Home over whatever the user had open.My fix teaches those two spots about the share, and nothing else:
ShareModalNavigatorunder the onboarding modal;dismissOnboardingModalBeforeExitdoesn't dismiss a modal that isn't onboarding;navigateAfterOnboardingskips the Home push while a share is open.As the video shows, onboarding comes first and the user lands back on the share afterwards. That's the same experience as the public-room flow.
Test Branch
WDYT @MelvinBot
2026-10-28.19-23-02.mp4
mukhrr commentedon Oct 28, 2026
I see Share coming first (1:13) in your video before onboarding and I think this should be fixed on public-room flow as well
MelvinBot commentedon Oct 28, 2026
I don't think this changes the decision. The public-room mechanism keeps a fullscreen route underneath onboarding, but it deliberately drops modals, and
ShareModalNavigatoris a modal. Keeping it there is a new exception to that rule. It also leaves three gaps that the selected proposal covers:Link.ts, so a share that arrives while the app is already running depends on main's existing deep-link replay.Details
RootStackRouter.ts:132-138cuts the stack at the first route inMODAL_ROUTES_TO_DISMISS, which includesSHARE_MODAL_NAVIGATOR. The comment there explains why: it prevents two stacked modals (Web - Onboarding - Two Expensify logos appear on the modal). fix: land new account on initially opened room added this branch, and its test checks that the SignIn modal is dropped while the fullscreen report is kept. A public room survives because it is a fullscreen route, not a modal.isReportTopmostSplitNavigator()asks whether the top fullscreen tab is Reports, so it can't tell whether a modal is open. You had to addhasOpenShareModal()as a new check.dismissOnboardingModalBeforeExitis safe today only because the router makes onboarding the only modal. Your router change removes that guarantee, so the dismiss needs a guard too.consumeDeepLinkToOpenAfterOnboarding()opens it at L139 and skips the router change. I traced this in code only and didn't test it on a device.FitseTLT commentedon Oct 28, 2026
This is not new behavior even on large screen onboarding modal opens on top of the underlying screen whethere it is Home or Inbox. When it is native on emulator it is slow and takes time before the modal opens even in normal case.
jayeshmangwani commentedon Oct 29, 2026
@mukhrr Nothing wrong with your proposal! I tested it, and it has the same behavior as the other proposals: the Share with expensify page appears before the onboarding flow. That’s why I decided to go with this approach #101425 (comment).
melvin-bot commentedon Oct 29, 2026
Current assignee @Gonals is eligible for the choreEngineerContributorManagement assigner, not assigning anyone new.
abbasifaizan70 commentedon Nov 2, 2026
@Gonals @jayeshmangwani The PR is ready for the review. Thanks
jeffrey-graham commentedon Nov 7, 2026
melvin-bot commentedon Nov 7, 2026
📣 @jeffrey-graham! 📣
Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
Please follow these steps:
Format: