Uh oh!
There was an error while loading. Please reload this page.
fix(react-router): Catch thrown nullish value and prevent nullish - #7741
fix(react-router): Catch thrown nullish value and prevent nullish#7741joseinaqa wants to merge 1 commit into
Conversation
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughCatchBoundary now normalizes nullish thrown errors and updates the stored stack before calling onCatch. Match now falls back to a shared never-resolving promise when Suspense would otherwise throw nothing, and client error rethrows now always produce a concrete Error. ChangesError and Suspense Handling Fixes
Estimated code review effort: 2 (Simple) | ~12 minutes Possibly related issues
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/react-router/src/Match.tsx`:
- Line 523: The Match.tsx error-handling path currently throws
permaPendingPromise when match.error is nullish, which keeps the route suspended
instead of reaching the error boundary. Update the logic in Match to throw a
synthetic Error in this branch, and keep using match.error when present so
client error states render correctly rather than staying on the pending
fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a7b45fc0-6aa0-4f09-8dcf-8eda61c7602c
📒 Files selected for processing (2)
packages/react-router/src/CatchBoundary.tsxpackages/react-router/src/Match.tsx
Uh oh!
There was an error while loading. Please reload this page.
dbd4754 to
61fa627Comparetristansinclair
commented
Jul 8, 2026
We hit this exact crash in production and independently arrived at essentially this same diff before finding this PR — so consider this a field test of the approach. Stack: React 19.2 SPA (no SSR), Vite, Debugger-confirmed throw site. Sentry only showed a stackless Deterministic reproduction shape. Cold load at This PR's approach fixes it. We shipped the equivalent change as a dist patch (below) and re-ran the same harness: 0/13 crashes across the same conditions and harsher variants (CPU-throttled, delayed auth responses, multi-hop redirect chains), with all navigations completing normally. Also verified the affected code is byte-identical in the latest release (1.170.17), so this isn't fixed by upgrading. One correctness nit: For anyone needing a stopgap while this PR is pending, here's the dist-level patch we're running in production via
|
61fa627 to
7760627CompareloadPromise from being thrown The issue happens in circumstances where match.status === 'redirected' but the loadPromise is nulled. Reproduction is possible by using https://github.com/joseinaqa/redirect-race-app and after this change does not anymore.
7760627 to
de1aaf2Compare- patch @tanstack/react-router (TanStack/router#7741): never throw a cleared loadPromise; coerce falsy CatchBoundary errors into real Errors - error boundary: bounded auto-reset for non-Error throws, then reload screen - runApi: coerce non-Error rejections into Errors (FiberFailure untouched) - reload on vite:preloadError so stale tabs survive deploys - guard test fails loudly if a version bump silently drops the patch
loadPromise from being thrown
The issue happens in circumstances where match.status === 'redirected' but the loadPromise is nulled.
Reproduction is possible by using
https://github.com/joseinaqa/redirect-race-app and after this change does not happen anymore.
Summary by CodeRabbit
Error.