Problem
Users on iOS production are hitting an infinite navigation loop crash during the onboarding flow. The app crashes with "Maximum update depth exceeded" (React error).
Sentry issue: https://expensify.sentry.io/issues/7332234716/
Symptoms
- Rapid, repeated navigation to
OnboardingModalNavigator visible in Sentry breadcrumbs
- VL logs show
[OnboardingGuard] Redirecting to onboarding route firing repeatedly with all boolean conditions as empty strings (serialized false/undefined)
- Not reproducible locally — appears to require a specific timing/state combination
Root Cause
The OnboardingGuard in src/libs/Navigation/guards/OnboardingGuard.ts lacks idempotency. When shouldSkipOnboarding is false, the guard unconditionally returns a REDIRECT to the onboarding route — even when the user is already on the OnboardingModalNavigator.
Each REDIRECT produces a CommonActions.reset() that changes the navigation state, which triggers:
onStateChange in NavigationRoot.tsx → Onyx writes (updateOnboardingLastVisitedPath)
- Re-renders from Onyx state changes
- Re-evaluation of the guard (via
useNavigationBuilder calling router.getStateForAction during render)
- Another
REDIRECT → another reset → loop continues until React hits maximum update depth
Additionally, getOnboardingInitialPath() (called by the guard to compute the redirect route) performs Onyx.set() side effects for certain user types (VSB, SMB, individual), which injects further state mutations into each loop iteration.
Fix
Add an idempotency check: if OnboardingModalNavigator is already present in state.routes, return ALLOW instead of issuing a redundant REDIRECT. This ensures the guard reaches a stable state after the first redirect.
Platform
Issue Owner
Current Issue Owner: @mallenexpensify
Issue Owner
Current Issue Owner: @mallenexpensify
Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~022044575911073373513
- Upwork Job ID: 2044575911073373513
- Last Price Increase: 2026-04-16
Problem
Users on iOS production are hitting an infinite navigation loop crash during the onboarding flow. The app crashes with "Maximum update depth exceeded" (React error).
Sentry issue: https://expensify.sentry.io/issues/7332234716/
Symptoms
OnboardingModalNavigatorvisible in Sentry breadcrumbs[OnboardingGuard] Redirecting to onboarding routefiring repeatedly with all boolean conditions as empty strings (serializedfalse/undefined)Root Cause
The
OnboardingGuardinsrc/libs/Navigation/guards/OnboardingGuard.tslacks idempotency. WhenshouldSkipOnboardingisfalse, the guard unconditionally returns aREDIRECTto the onboarding route — even when the user is already on theOnboardingModalNavigator.Each
REDIRECTproduces aCommonActions.reset()that changes the navigation state, which triggers:onStateChangeinNavigationRoot.tsx→ Onyx writes (updateOnboardingLastVisitedPath)useNavigationBuildercallingrouter.getStateForActionduring render)REDIRECT→ another reset → loop continues until React hits maximum update depthAdditionally,
getOnboardingInitialPath()(called by the guard to compute the redirect route) performsOnyx.set()side effects for certain user types (VSB, SMB, individual), which injects further state mutations into each loop iteration.Fix
Add an idempotency check: if
OnboardingModalNavigatoris already present instate.routes, returnALLOWinstead of issuing a redundantREDIRECT. This ensures the guard reaches a stable state after the first redirect.Platform
Issue Owner
Current Issue Owner: @mallenexpensifyIssue Owner
Current Issue Owner: @mallenexpensifyUpwork Automation - Do Not Edit