Skip to content

[Due for payment 2026-10-23] [$175] [DEV] Console error on startup #101938

Open

Description

@izarutskaya

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


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:

  1. Launch the Android HybridApp
  2. 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:

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

Screenshots/Videos

View all open jobs on GitHub

Issue OwnerCurrent Issue Owner: @mallenexpensify
Upwork Automation - Do Not Edit

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 22, 2026
  2. MelvinBot commented on Sep 22, 2026

    @MelvinBot
    Contributor

    ⚠️ 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 ReportsSplitNavigator route 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:

    // src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx, inside ReportsSplitNavigator()
    console.log('ReportsSplitNavigator params', JSON.stringify(route.params));

    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:

    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:


    Next Steps: Reply with @MelvinBot <your feedback> to refine this analysis, or paste the route.params output above and I'll pin the root cause.


    view run

  3. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Sep 22, 2026
  4. melvin-bot commented on Sep 22, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @thesahindia (External)

  5. melvin-bot commented on Sep 22, 2026

    @melvin-bot

    Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.

  6. ashusatyarthi-wq commented on Sep 27, 2026

    @ashusatyarthi-wq

    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 useNavigationBuilder hook in @react-navigation/core (useNavigationBuilder.tsx:766). It is triggered by two interconnected root causes:

    1. Stale Params Re-dispatch via navigation.setParams in ReportsSplitNavigator.tsx:
      In src/libs/Navigation/AppNavigator/Navigators/ReportsSplitNavigator.tsx (lines 70–75):

      useEffect(() => {
          if (!shouldClearInitialReportActionsDefer) {
              return;
          }
          navigation.setParams({shouldDeferInitialReportActions: undefined});
      }, [navigation, shouldClearInitialReportActionsDefer]);

      When navigating to the Inbox via InboxTabButton.tsx (lines 157–166), TabActions.jumpTo dispatches nested params to NAVIGATORS.REPORTS_SPLIT_NAVIGATOR:

      {
          screen: SCREENS.REPORT,
          shouldDeferInitialReportActions: true,
          params: { reportID, ... }
      }

      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) {
              const action = CommonActions.navigate(route.params.screen, route.params.params);
              const isSuccess = 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.

    2. 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:

    1. 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:

      useEffect(() => {
          if (!shouldClearInitialReportActionsDefer) {
              return;
          }
          navigation.setParams({
              shouldDeferInitialReportActions: undefined,
              screen: undefined,
              params: undefined,
          });
      }, [navigation, shouldClearInitialReportActionsDefer]);
    2. 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:

      if (action.type === CONST.NAVIGATION.ACTION_TYPE.NAVIGATE && action.payload.name === state.routes.at(-1)?.name) {
          const result = stackRouter.getStateForAction(state, action, configOptions);
          return result ? stripSkipInitialSidebarParam(result) : state;
      }

      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.
  7. ashusatyarthi-wq commented on Sep 27, 2026

    @ashusatyarthi-wq

    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

    • 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.
  8. melvin-bot commented on Sep 28, 2026

    @melvin-bot

    @thesahindia Eep! 4 days overdue now. Issues have feelings too...

  9. melvin-bot commented on Sep 30, 2026

    @melvin-bot

    @thesahindia Still overdue 6 days?! Let's take care of this!

  10. 19 remaining items

  11. changed the title [-][$175] [DEV] Console error on startup[/-] [+][Due for payment 2026-10-23] [$175] [DEV] Console error on startup[/+] on Oct 16, 2026
  12. melvin-bot commented on Oct 16, 2026

    @melvin-bot

    @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]

  13. melvin-bot commented on Oct 19, 2026

    @melvin-bot

    @Krishna2323 Whoops! This issue is 2 days overdue. Let's get this updated quick!

  14. melvin-bot commented on Oct 21, 2026

    @melvin-bot

    @Krishna2323 Eep! 4 days overdue now. Issues have feelings too...

  15. melvin-bot commented on Oct 22, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  16. melvin-bot commented on Oct 22, 2026

    @melvin-bot

    Payment Summary

    Resolving PRs:

    BugZero Checklist (@mallenexpensify)

    • I have confirmed assignees, roles, and Upwork contracts look correct
    • I have paid out Upwork contracts / manual NewDot requests
    • [BugZero Assignee] I have created a GH issue for creating/updating the regression test once above steps have been agreed upon
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.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions