Which project does this relate to?
Router
Describe the bug
notFound() thrown from an async loader renders the component (with undefined loaderData) instead of notFoundComponent. Regression from v1.162 → v1.168.
handleRedirectAndNotFound (load-matches.ts:137) changed from always setting status: "notFound" to setting "success" when pending:
// v1.162 (correct)
const status = isRedirect(err) ? "redirected" : "notFound";
// v1.168 (broken — load-matches.ts:137-141)
status: isRedirect(err) ? "redirected" : prev.status === "pending" ? "success" : prev.status
This relies on loadMatches (load-matches.ts:1110) to set the final "notFound" later. But React can flush a render between the two via processRootScheduleInMicrotask, reading the intermediate "success" status in Match.tsx:437.
Fix (load-matches.ts:137):
- status: isRedirect(err) ? "redirected" : prev.status === "pending" ? "success" : prev.status,
+ status: isRedirect(err) ? "redirected" : isNotFound(err) ? "notFound" : prev.status === "pending" ? "success" : prev.status,
Your Example Website or App
No minimal repro - race condition that depends on real world loader timing. Happy to work with maintainers to reproduce if issue details not sufficient.
Steps to Reproduce the Bug or Issue
- Parent route with fast/sync loader, child route with async loader that throws
notFound() after await
- Child route has
notFoundComponent
- Navigate directly to child URL
- When parent resolves first, React renders parent → Outlet subscribes to child match store → child throws →
handleRedirectAndNotFound (L137) sets "success" → React flushes → Match.tsx:437 sees "success" → component renders with undefined loaderData
Expected behavior
notFoundComponent renders.
Screenshots or Videos
No response
Platform
- Router: 1.168.19 (router-core 1.168.14)
- OS: macOS
- Browser: Chrome
- Bundler: Vite 8
Additional context
No response
Which project does this relate to?
Router
Describe the bug
notFound()thrown from an async loader renders the component (withundefinedloaderData) instead ofnotFoundComponent. Regression from v1.162 → v1.168.handleRedirectAndNotFound(load-matches.ts:137) changed from always settingstatus: "notFound"to setting"success"when pending:This relies on
loadMatches(load-matches.ts:1110) to set the final"notFound"later. But React can flush a render between the two viaprocessRootScheduleInMicrotask, reading the intermediate"success"status inMatch.tsx:437.Fix (
load-matches.ts:137):Your Example Website or App
No minimal repro - race condition that depends on real world loader timing. Happy to work with maintainers to reproduce if issue details not sufficient.
Steps to Reproduce the Bug or Issue
notFound()afterawaitnotFoundComponenthandleRedirectAndNotFound(L137) sets"success"→ React flushes →Match.tsx:437sees"success"→ component renders withundefinedloaderDataExpected behavior
notFoundComponentrenders.Screenshots or Videos
No response
Platform
Additional context
No response