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
[$175] [Exploratory] Login-Pre-filled amount is shown when creating expense via shortcut. #101340
Version Number: V9.4.80-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://github.com/Expensify/Mobile-Expensify/pull/14085 Email or phone of affected tester (no customers):dreamnitethedragon+vegst@gmail.com Issue reported by: Applause Internal Team Bug source: Exploratory - Significant User Experience Deterioration Device used: Redmi note 10s android 13 App Component: Money Requests
Action Performed:
Scenario 1
Login gmail via track business expenses
Go to home and Kill app
Long press app and select create expense
Enter amount and tap center navigation button
Long press app and select create expense
Note pre-filled amount is shown
Scenario 2
Login gmail via track business expenses
Go to home and Kill app
Long press app and select create expense
Enter amount and tap center navigation button
Long press app and select distance expense
Tap center navigation button
Long press app and select create expense
Note amount field is empty ( expected)
Enter amount and tap center navigation button
Long press app and select distance expense
Tap center navigation button
Long press app and select create expense
Note pre-filled amount is shown
Expected Result:
Pre-filled amount must not be shown when creating expense via shortcut.
Actual Result:
Pre-filled amount is shown when creating expense via shortcut.
Please re-state the problem that we are trying to solve in this issue.
When you open "Create expense" from the Android app shortcut a second time, the amount from the last unfinished expense is still shown.
What is the root cause of that problem?
The shortcut deep link goes straight to the create screen for the shared draft transaction (OPTIMISTIC_TRANSACTION_ID). Nothing on that path clears the old draft. The inline amount field saves the amount to the draft on every keystroke, so the amount outlives the screen.
The draft is reset in only two cases, and neither one happens here:
Same screen is still open (Scenario 1). The /manual skip rule in subscribe.ts:20 drops the second shortcut link because the manual tab is already focused. The old screen and draft stay.
Screen remounts.resetIOUTypeIfChanged exits early when the draft's request type matches the new one (useResetIOUType.ts:100). A manual draft opened as manual again keeps its amount.
This also explains Scenario 2. On the first distance visit, the distance tab is not saved yet, so switching tabs changes the type and the draft is rebuilt with no amount. On the second visit, the tab is already saved, the draft type stays manual, and the amount survives.
What changes do you think we should make in order to solve the problem?
In subscribe.ts, after the skip checks and before listener(url), detect shortcut create URLs (/create/<type>/start/1/<reportID>/manual|scan|distance-new). Call clearMoneyRequest(OPTIMISTIC_TRANSACTION_ID, ...) for them, the same way IOURequestRedirectToStartPage does. The page then remounts with no draft, and useResetIOUType builds a fresh one.
Do the same for a cold start in the initial-URL path of DeepLinkHandler.
Narrow the /manual skip rule so it still drops the link when the draft is empty, but not when it has an amount (isAmountSet). Otherwise Scenario 1 still fails because the link never reaches navigation.
What alternative solutions did you explore? (Optional)
Reset on the page. Force a full re-init in useResetIOUType when the draft is stale (IOURequestStartPage already computes a stale flag, and DistanceRequestStartPage would need the same). This is riskier: a web refresh on a create URL could wipe input the user just typed.
Point the shortcut at the start/... route, which already clears the draft. That change is outside the App repo, and step 3 is still needed.
Each keystroke calls setMoneyRequestAmount, which sets amount and isAmountSet: true on the draft. The field then reads the stored value on mount.
onTabSelected in OnyxTabNavigator fires only when the tab differs from the saved tab, which is why the second distance visit does not reset the draft.
Not verified on a device: the exact shortcut URL, and that the "center navigation button" is the Android Home button. Both scenarios match this reading of the code.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/101340) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
It clears the stale draft when a shortcut opens the create screen:
Create screen not open: the draft is cleared before the link navigates, so the screen builds a fresh one (Scenario 2).
Manual tab already open: the link is still dropped to avoid re-navigating, but the amount is cleared in place (Scenario 1).
Cold start: the draft is cleared before the first screen mounts. This runs only on iOS and Android, so a web refresh keeps the user's input.
GPS links are left alone so a tracked trip isn't lost.
I haven't tested this on a device. Unit tests, typecheck, lint, and spell check pass. Please run both scenarios on Android with a build of this branch.
Please re-state the problem that we are trying to solve in this issue.
When you open "Create expense" from the app shortcut again, the amount from the last unfinished expense is still shown.
What is the root cause of that problem?
The shortcut opens the create screen directly for the shared draft (OPTIMISTIC_TRANSACTION_ID). It skips the start/... redirect, which is the only place that clears the old draft (IOURequestRedirectToStartPage.tsx:49). The amount field saves each keystroke to the draft, so the amount outlives the screen.
Nothing else resets it:
Scenario 1: the manual tab is still focused, so the /manual skip rule drops the new link (subscribe.ts:20). The old screen and amount stay.
Scenario 2: the screen remounts, but resetIOUTypeIfChanged exits early when the draft is already manual (useResetIOUType.ts:100). The first distance visit changes the saved tab and rebuilds the draft. The second visit does not, so the amount survives.
What changes do you think we should make in order to solve the problem?
Clear the old draft whenever a shortcut create link arrives. A shortcut create link matches /create/<type>/start/1/<reportID>/manual|scan|distance-new.
Link arrives while the app is running (subscribe.ts): clear the draft before passing the link on. The screen then builds a fresh draft.
Manual tab already open (subscribe.ts): keep dropping the link so the screen does not re-navigate, but reset the amount in place (amount: 0, isAmountSet: false).
Cold start (DeepLinkHandler): clear the draft before the first screen mounts. Run this only on iOS and Android, and only once, so a web refresh keeps what the user typed.
Skip GPS links (.../distance-gps), because they reopen a trip that is still being tracked.
Put the two Onyx writes in a small module that imports only Onyx. Importing MoneyRequest from linkingConfig creates a circular import.
Add unit tests for each case in linkingConfigSubscribeTest.
What alternative solutions did you explore? (Optional)
Reset on the page when the draft is stale. This is riskier: a web refresh on a create URL could wipe input.
Point the shortcut at the start/... route. That change is outside the App repo, and Scenario 1 would still need step 2.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/101340) to create a draft PR. The draft PR above already implements it. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
changed the title [-][Exploratory] Login-Pre-filled amount is shown when creating expense via shortcut.[/-][+][$175] [Exploratory] Login-Pre-filled amount is shown when creating expense via shortcut.[/+]on Oct 23, 2026
Activity
applause-bot commentedon Sep 16, 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/54867d38c1d0ac06e8db4cb3d1806fdd914bc2de5f4d2ddb5754e6b92ad3dc76
MelvinBot commentedon Sep 26, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
When you open "Create expense" from the Android app shortcut a second time, the amount from the last unfinished expense is still shown.
What is the root cause of that problem?
The shortcut deep link goes straight to the create screen for the shared draft transaction (
OPTIMISTIC_TRANSACTION_ID). Nothing on that path clears the old draft. The inline amount field saves the amount to the draft on every keystroke, so the amount outlives the screen.The draft is reset in only two cases, and neither one happens here:
/manualskip rule insubscribe.ts:20drops the second shortcut link because the manual tab is already focused. The old screen and draft stay.resetIOUTypeIfChangedexits early when the draft's request type matches the new one (useResetIOUType.ts:100). A manual draft opened as manual again keeps its amount.This also explains Scenario 2. On the first distance visit, the distance tab is not saved yet, so switching tabs changes the type and the draft is rebuilt with no amount. On the second visit, the tab is already saved, the draft type stays
manual, and the amount survives.The in-app start route does clear the draft (
IOURequestRedirectToStartPage.tsx:43), but the shortcut does not go through it.What changes do you think we should make in order to solve the problem?
subscribe.ts, after the skip checks and beforelistener(url), detect shortcut create URLs (/create/<type>/start/1/<reportID>/manual|scan|distance-new). CallclearMoneyRequest(OPTIMISTIC_TRANSACTION_ID, ...)for them, the same wayIOURequestRedirectToStartPagedoes. The page then remounts with no draft, anduseResetIOUTypebuilds a fresh one.DeepLinkHandler./manualskip rule so it still drops the link when the draft is empty, but not when it has an amount (isAmountSet). Otherwise Scenario 1 still fails because the link never reaches navigation.What alternative solutions did you explore? (Optional)
useResetIOUTypewhen the draft is stale (IOURequestStartPagealready computes a stale flag, andDistanceRequestStartPagewould need the same). This is riskier: a web refresh on a create URL could wipe input the user just typed.start/...route, which already clears the draft. That change is outside the App repo, and step 3 is still needed.Supporting evidence
setMoneyRequestAmount, which setsamountandisAmountSet: trueon the draft. The field then reads the stored value on mount.onTabSelectedinOnyxTabNavigatorfires only when the tab differs from the saved tab, which is why the second distance visit does not reset the draft.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/101340)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 29, 2026
@aimane-chnaif Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
aimane-chnaif commentedon Oct 1, 2026
@MelvinBot draft PR for testing
MelvinBot commentedon Oct 1, 2026
🤖 Draft PR created: Clear the old expense draft when a quick-action shortcut opens the create screen
Please mark it as "Ready for review" when it is ready for review.
It clears the stale draft when a shortcut opens the create screen:
GPS links are left alone so a tracked trip isn't lost.
I haven't tested this on a device. Unit tests, typecheck, lint, and spell check pass. Please run both scenarios on Android with a build of this branch.
view run
melvin-bot commentedon Oct 6, 2026
@aimane-chnaif Huh... This is 4 days overdue. Who can take care of this?
1 remaining item
melvin-bot commentedon Oct 12, 2026
@aimane-chnaif 10 days overdue. I'm getting more depressed than Marvin.
melvin-bot commentedon Oct 14, 2026
@aimane-chnaif 12 days overdue. Walking. Toward. The. Light...
melvin-bot commentedon Oct 19, 2026
This issue has not been updated in over 14 days. @aimane-chnaif eroding to Weekly issue.
MelvinBot commentedon Oct 23, 2026
Proposal
This updates my earlier proposal to match the approach in the draft PR Clear the old expense draft when a quick-action shortcut opens the create screen. That PR passed both scenarios on an Android build.
Please re-state the problem that we are trying to solve in this issue.
When you open "Create expense" from the app shortcut again, the amount from the last unfinished expense is still shown.
What is the root cause of that problem?
The shortcut opens the create screen directly for the shared draft (
OPTIMISTIC_TRANSACTION_ID). It skips thestart/...redirect, which is the only place that clears the old draft (IOURequestRedirectToStartPage.tsx:49). The amount field saves each keystroke to the draft, so the amount outlives the screen.Nothing else resets it:
/manualskip rule drops the new link (subscribe.ts:20). The old screen and amount stay.resetIOUTypeIfChangedexits early when the draft is alreadymanual(useResetIOUType.ts:100). The first distance visit changes the saved tab and rebuilds the draft. The second visit does not, so the amount survives.What changes do you think we should make in order to solve the problem?
Clear the old draft whenever a shortcut create link arrives. A shortcut create link matches
/create/<type>/start/1/<reportID>/manual|scan|distance-new.subscribe.ts): clear the draft before passing the link on. The screen then builds a fresh draft.subscribe.ts): keep dropping the link so the screen does not re-navigate, but reset the amount in place (amount: 0,isAmountSet: false).DeepLinkHandler): clear the draft before the first screen mounts. Run this only on iOS and Android, and only once, so a web refresh keeps what the user typed..../distance-gps), because they reopen a trip that is still being tracked.MoneyRequestfromlinkingConfigcreates a circular import.linkingConfigSubscribeTest.What alternative solutions did you explore? (Optional)
start/...route. That change is outside the App repo, and Scenario 1 would still need step 2.Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/101340)to create a draft PR. The draft PR above already implements it.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run
melvin-bot commentedon Oct 23, 2026
Current assignee @aimane-chnaif is eligible for the External assigner, not assigning anyone new.
[-][Exploratory] Login-Pre-filled amount is shown when creating expense via shortcut.[/-][+][$175] [Exploratory] Login-Pre-filled amount is shown when creating expense via shortcut.[/+]melvin-bot commentedon Oct 23, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022113427059548718342
aimane-chnaif commentedon Oct 23, 2026
I ended up opening my own PR since Melvin's solution is wrong.
Scenario 1 is not bug.
Scenario 2 is bug. And that root cause leads to another bad bug below. The PR fixes both.
Expected Result: The Start address search opens.
Actual Result: "Hmm... it's not here" / "Oops, this page cannot be found".
bug.mov