Skip to content

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

Closed

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions