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-23] [$175] [DEV] Console error on startup #101938
Version Number: Reproducible in staging?: v9.4.91-0 Develop Reproducible in production?: v9.4.91-0 Develop If this was caught during regression testing, add the test name, ID and link from BrowserStack: Email or phone of affected tester (no customers): Logs:https://stackoverflow.com/c/expensify/questions/4856 Expensify/Expensify Issue URL: Issue reported by:@QichenZhu Slack conversation (hyperlinked to channel name): #expensify_bugs
Action Performed:
Launch the Android HybridApp
Open the Inbox.
Expected Result:
No console errors
Actual Result:
Console error appears: The 'state' or 'screen' passed in the params couldn't be applied to the navigator with the screens: 'Inbox', 'Report'.
Workaround:
Unknown
Platforms:
Select the officially supported platforms where the issue was reproduced:
⚠️Preliminary analysis (low confidence) — treat as a starting point, not a conclusion. I could not drive the app in a browser or on an emulator in this run, so nothing below is runtime-verified.
What the error means
The warning comes from React Navigation itself (@react-navigation/core@7.21.12, useNavigationBuilder.tsx:766), not from our code. It is wrapped in a process.env.NODE_ENV !== 'production' check, which is why it only shows up in dev builds.
The navigator it names — screens 'Inbox' and 'Report' — is uniquely ReportsSplitNavigator. Those are the only two screens it registers.
It fires when the ReportsSplitNavigatorroute inside TAB_NAVIGATOR carries nested navigation params (params.screen or params.state) and the router rejects them. There are exactly two rejection paths:
params.screen → a NAVIGATE action. StackRouter returns null only when the name is not Inbox or Report.
params.state → a CommonActions.reset. BaseRouter returns null when routes is empty, when any route name is not Inbox/Report, or — for a non-stale state — when routeNames or index don't line up.
So something is handing this navigator a nested screen/state that doesn't belong to it. The navigation is then discarded, which is why the app still looks fine.
How to pin it down
Log the params the navigator actually receives — this prints the offending value directly:
Run the Android HybridApp, open the Inbox, and compare that output against the error.
Call sites that write nested params onto this route
These are the places I found that can put screen/state on the ReportsSplitNavigator route. All of them look correct on a static read — each passes SCREENS.REPORT or a state built from Inbox/Report — so the bug is likely in the value one of them computes at startup, not in the shape of the call:
src/libs/Navigation/helpers/linkTo/index.ts:292 — injects a whole state object into the split navigator's params when the matching full-screen route has never been visited. A state sourced from a different navigator would trip the RESET rejection path above.
src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx:74 — navigation.setParams({shouldDeferInitialReportActions: undefined}). Worth knowing: this creates a new params object, which drops React Navigation's consumedParams WeakMap entry and makes the navigator re-apply the nested params on the next render. That alone shouldn't error, but it does mean the nested-param path runs more than once on startup.
Also relevant: the HybridApp start-up path goes through /transition?exitTo=… and then Navigation.navigate(exitTo), so the offending params may originate from the exitTo value OldDot hands over rather than from an in-app tap. That part is HybridApp-specific and needs the Android HybridApp build to observe.
Related issues
I scanned open Expensify/App issues and found no duplicate. Possibly related, but a different symptom:
Please re-state the problem that we are trying to solve in this issue.
On startup of the Android HybridApp, opening the Inbox produces a React Navigation console warning in development: The 'state' or 'screen' passed in the params couldn't be applied to the navigator with the screens: 'Inbox', 'Report'.
What is the root cause of that problem?
The warning is emitted by React Navigation's useNavigationBuilder hook in @react-navigation/core (useNavigationBuilder.tsx:766). It is triggered by two interconnected root causes:
Stale Params Re-dispatch via navigation.setParams in ReportsSplitNavigator.tsx:
In src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx (lines 70–75):
On initial mount, useNavigationBuilder consumes screen: SCREENS.REPORT and successfully mounts the screen.
Immediately afterwards, ReportsSplitNavigator's useEffect calls navigation.setParams({shouldDeferInitialReportActions: undefined}).
In React Navigation, navigation.setParams replaces route.params with a brand new object reference. Because route.params is in useNavigationBuilder's dependency array:
React.useEffect(()=>{if(route.params?.screen){constaction=CommonActions.navigate(route.params.screen,route.params.params);constisSuccess=navigation.dispatch(action);if(!isSuccess){warn(false,`The 'state' or 'screen' passed in the params couldn't be applied to the navigator with the screens: ${Object.keys(screens).map((s)=>`'${s}'`).join(', ')}.`);}}},[route.params]);
React Navigation sees route.params.screen: SCREENS.REPORT on the new params object and attempts to re-dispatch NAVIGATE to SCREENS.REPORT.
SplitRouter / StackRouter Returns null on Idempotent Navigation:
When useNavigationBuilder re-dispatches NAVIGATE for SCREENS.REPORT, SCREENS.REPORT is already the focused, active top screen in the stack with identical params.
React Navigation's StackRouter.getStateForAction treats navigating to the already-focused screen with unchanged params as a no-op and returns null. navigation.dispatch translates a null router response into isSuccess = false, which causes useNavigationBuilder to falsely assume the nested screen parameter was invalid and log the warning.
What changes do you think we should make in order to solve the problem?
We should resolve this at both levels for complete reliability:
Clear Consumed Navigation Params in ReportsSplitNavigator.tsx:
In src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx:
When shouldClearInitialReportActionsDefer is true, clear screen and params along with shouldDeferInitialReportActions so stale nested navigation directives do not linger on the route:
Handle Idempotent Navigation Gracefully in SplitRouter.ts:
In src/libs/Navigation/AppNavigator/createSplitNavigator/SplitRouter.ts:
In getStateForAction, when action.type === CONST.NAVIGATION.ACTION_TYPE.NAVIGATE and the target screen matches the currently active screen (action.payload.name === state.routes.at(-1)?.name), return state instead of null if stackRouter.getStateForAction returns null:
Returning state signifies that the navigator successfully recognized and satisfied the navigation request, preventing useNavigationBuilder from logging the false-positive warning.
What alternative solutions did you explore? (Optional)
Only updating SplitRouter.ts: While returning state in SplitRouter silences the warning, leaving stale screen and params inside route.params leaves unnecessary nested parameters in the tab navigation state that are re-evaluated whenever other params update.
Only clearing params in ReportsSplitNavigator.tsx: Does not protect against external deeplinks or synthetic linkTo actions that may re-target the currently focused central screen.
Combining both ensures clean state hygiene and resilient router behavior.
Clears consumed screen and params alongside shouldDeferInitialReportActions in ReportsSplitNavigator.tsx.
Gracefully handles idempotent NAVIGATE actions targeting the currently active screen in SplitRouter.ts by returning state instead of null, preventing false-positive navigation builder warnings.
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.12-1 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-23. 🎊
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
MelvinBot commentedon Sep 22, 2026
What the error means
The warning comes from React Navigation itself (
@react-navigation/core@7.21.12,useNavigationBuilder.tsx:766), not from our code. It is wrapped in aprocess.env.NODE_ENV !== 'production'check, which is why it only shows up in dev builds.The navigator it names — screens
'Inbox'and'Report'— is uniquelyReportsSplitNavigator. Those are the only two screens it registers.It fires when the
ReportsSplitNavigatorroute insideTAB_NAVIGATORcarries nested navigation params (params.screenorparams.state) and the router rejects them. There are exactly two rejection paths:params.screen→ aNAVIGATEaction.StackRouterreturnsnullonly when the name is notInboxorReport.params.state→ aCommonActions.reset.BaseRouterreturnsnullwhenroutesis empty, when any route name is notInbox/Report, or — for a non-stale state — whenrouteNamesorindexdon't line up.So something is handing this navigator a nested
screen/statethat doesn't belong to it. The navigation is then discarded, which is why the app still looks fine.How to pin it down
Log the params the navigator actually receives — this prints the offending value directly:
Run the Android HybridApp, open the Inbox, and compare that output against the error.
Call sites that write nested params onto this route
These are the places I found that can put
screen/stateon theReportsSplitNavigatorroute. All of them look correct on a static read — each passesSCREENS.REPORTor a state built fromInbox/Report— so the bug is likely in the value one of them computes at startup, not in the shape of the call:src/components/Navigation/NavigationTabBar/InboxTabButton.tsx:157—TabActions.jumpTo(REPORTS_SPLIT_NAVIGATOR, {screen: SCREENS.REPORT, params: {...}}). This is the tap handler for the Inbox tab, so it is directly on the reported path.src/libs/Navigation/helpers/linkTo/index.ts:292— injects a wholestateobject into the split navigator's params when the matching full-screen route has never been visited. Astatesourced from a different navigator would trip theRESETrejection path above.src/libs/Navigation/helpers/linkTo/index.ts:167-178—getMatchingFullScreenRouteParamsbuilds{screen: lastRoute.name, params: {..., state: lastRoute.state}}from the live tree.src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx:74—navigation.setParams({shouldDeferInitialReportActions: undefined}). Worth knowing: this creates a new params object, which drops React Navigation'sconsumedParamsWeakMap entry and makes the navigator re-apply the nested params on the next render. That alone shouldn't error, but it does mean the nested-param path runs more than once on startup.Also relevant: the HybridApp start-up path goes through
/transition?exitTo=…and thenNavigation.navigate(exitTo), so the offending params may originate from theexitTovalue OldDot hands over rather than from an in-app tap. That part is HybridApp-specific and needs the Android HybridApp build to observe.Related issues
I scanned open
Expensify/Appissues and found no duplicate. Possibly related, but a different symptom:Next Steps: Reply with
@MelvinBot <your feedback>to refine this analysis, or paste theroute.paramsoutput above and I'll pin the root cause.view run
melvin-bot commentedon Sep 22, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @thesahindia (
External)melvin-bot commentedon Sep 22, 2026
Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.
ashusatyarthi-wq commentedon Sep 27, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
On startup of the Android HybridApp, opening the Inbox produces a React Navigation console warning in development:
The 'state' or 'screen' passed in the params couldn't be applied to the navigator with the screens: 'Inbox', 'Report'.What is the root cause of that problem?
The warning is emitted by React Navigation's
useNavigationBuilderhook in@react-navigation/core(useNavigationBuilder.tsx:766). It is triggered by two interconnected root causes:Stale Params Re-dispatch via
navigation.setParamsinReportsSplitNavigator.tsx:In
src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx(lines 70–75):When navigating to the Inbox via
InboxTabButton.tsx(lines 157–166),TabActions.jumpTodispatches nested params toNAVIGATORS.REPORTS_SPLIT_NAVIGATOR:On initial mount,
useNavigationBuilderconsumesscreen: SCREENS.REPORTand successfully mounts the screen.Immediately afterwards,
ReportsSplitNavigator'suseEffectcallsnavigation.setParams({shouldDeferInitialReportActions: undefined}).In React Navigation,
navigation.setParamsreplacesroute.paramswith a brand new object reference. Becauseroute.paramsis inuseNavigationBuilder's dependency array:React Navigation sees
route.params.screen: SCREENS.REPORTon the new params object and attempts to re-dispatchNAVIGATEtoSCREENS.REPORT.SplitRouter/StackRouterReturnsnullon Idempotent Navigation:When
useNavigationBuilderre-dispatchesNAVIGATEforSCREENS.REPORT,SCREENS.REPORTis already the focused, active top screen in the stack with identical params.React Navigation's
StackRouter.getStateForActiontreats navigating to the already-focused screen with unchanged params as a no-op and returnsnull.navigation.dispatchtranslates anullrouter response intoisSuccess = false, which causesuseNavigationBuilderto falsely assume the nested screen parameter was invalid and log the warning.What changes do you think we should make in order to solve the problem?
We should resolve this at both levels for complete reliability:
Clear Consumed Navigation Params in
ReportsSplitNavigator.tsx:In
src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx:When
shouldClearInitialReportActionsDeferis true, clearscreenandparamsalong withshouldDeferInitialReportActionsso stale nested navigation directives do not linger on the route:Handle Idempotent Navigation Gracefully in
SplitRouter.ts:In
src/libs/Navigation/AppNavigator/createSplitNavigator/SplitRouter.ts:In
getStateForAction, whenaction.type === CONST.NAVIGATION.ACTION_TYPE.NAVIGATEand the target screen matches the currently active screen (action.payload.name === state.routes.at(-1)?.name), returnstateinstead ofnullifstackRouter.getStateForActionreturnsnull:Returning
statesignifies that the navigator successfully recognized and satisfied the navigation request, preventinguseNavigationBuilderfrom logging the false-positive warning.What alternative solutions did you explore? (Optional)
SplitRouter.ts: While returningstateinSplitRoutersilences the warning, leaving stalescreenandparamsinsideroute.paramsleaves unnecessary nested parameters in the tab navigation state that are re-evaluated whenever other params update.ReportsSplitNavigator.tsx: Does not protect against external deeplinks or syntheticlinkToactions that may re-target the currently focused central screen.Combining both ensures clean state hygiene and resilient router behavior.
fix: clear consumed screen params when clearing report actions defer (E…
ashusatyarthi-wq commentedon Sep 27, 2026
Live Compare Branch & Patch
For convenient verification, I have published a working patch branch against latest
main:🔗 Compare: main...ashusatyarthi-wq:App:fix/navigator-warning-startup-101938
screenandparamsalongsideshouldDeferInitialReportActionsinReportsSplitNavigator.tsx.NAVIGATEactions targeting the currently active screen inSplitRouter.tsby returningstateinstead ofnull, preventing false-positive navigation builder warnings.fix: return active state for idempotent navigate actions in SplitRout…
melvin-bot commentedon Sep 28, 2026
@thesahindia Eep! 4 days overdue now. Issues have feelings too...
melvin-bot commentedon Sep 30, 2026
@thesahindia Still overdue 6 days?! Let's take care of this!
19 remaining items
[-][$175] [DEV] Console error on startup[/-][+][Due for payment 2026-10-23] [$175] [DEV] Console error on startup[/+]melvin-bot commentedon Oct 16, 2026
@Krishna2323
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.12-1 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-23. 🎊
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 19, 2026
@Krishna2323 Whoops! This issue is 2 days overdue. Let's get this updated quick!
melvin-bot commentedon Oct 21, 2026
@Krishna2323 Eep! 4 days overdue now. Issues have feelings too...
melvin-bot commentedon Oct 22, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Oct 22, 2026
Payment Summary
Resolving PRs:
Keep split navigator state when navigating to the only sidebar screen on narrow layout #103746
Reviewer: @Krishna2323 owed $175 via NewDot
BugZero Checklist (@mallenexpensify)