Skip to content

notFound() from async loader renders component instead of notFoundComponent #7179

@roduyemi

Description

@roduyemi

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

  1. Parent route with fast/sync loader, child route with async loader that throws notFound() after await
  2. Child route has notFoundComponent
  3. Navigate directly to child URL
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions