{"record":{"id":"15914658e43778cb","repo":"remix-run/react-router","slug":"unable-to-fetch-new-route-matches-from-the-server","errorCode":null,"errorMessage":"Unable to fetch new route matches from the server","messagePattern":"Unable to fetch new route matches from the server","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/rsc/browser.tsx","lineNumber":1096,"sourceCode":"  // step and just let discovery happen on link click.  We also wipe out the\n  // nextPaths Set here so we can start filling it with fresh links\n  if (url.toString().length > URL_LIMIT) {\n    nextPaths.clear();\n    return;\n  }\n\n  let response = await fetchImplementation(new Request(url, { signal }));\n  if (\n    clientVersion !== undefined &&\n    response.status === 204 &&\n    response.headers.has(\"X-Remix-Reload-Document\")\n  ) {\n    await handleClientVersionMismatch(true, clientVersion, errorReloadPath);\n    return;\n  }\n\n  if (!response.body || response.status < 200 || response.status >= 300) {\n    throw new Error(\"Unable to fetch new route matches from the server\");\n  }\n\n  let payload = (await createFromReadableStream(response.body, {\n    temporaryReferences: undefined,\n  })) as RSCPayload;\n  if (payload.type !== \"manifest\") {\n    throw new Error(\"Failed to patch routes\");\n  }\n\n  // Track discovered paths so we don't have to fetch them again\n  paths.forEach((p) => addToFifoQueue(p, discoveredPaths));\n\n  let patches = await payload.patches;\n\n  // Without the `allowElementMutations` flag, this will no-op if the route\n  // already exists so we can just call it for all returned patches\n  React.startTransition(() => {\n    patches.forEach((p) => {","sourceCodeStart":1078,"sourceCodeEnd":1114,"githubUrl":"https://github.com/remix-run/react-router/blob/7aea711dd1ae2bc5a076d13ff17291829690fa74/packages/react-router/lib/rsc/browser.tsx#L1078-L1114","documentation":"With lazy route discovery (the default in RSC framework mode), navigating to a path the client hasn't seen triggers a manifest fetch (`/__manifest`) to learn new routes. If that fetch fails at the transport level — no body, or a status outside 200–299 — this error is thrown and the navigation errors into the boundary. The 204 + `X-Remix-Reload-Document` case is handled separately as a version-mismatch reload, so plain 4xx/5xx or empty bodies are what land here.","triggerScenarios":"The `/__manifest` endpoint returning 404/500 because a custom server or adapter doesn't implement it; auth middleware blocking the manifest request; deploys where manifest files are missing from the static host; offline or network-level failures during navigation to undiscovered routes.","commonSituations":"Custom servers/edge handlers that route everything to the app and never define `__manifest`; hosting that drops the manifest asset; tests stubbing fetch without covering the manifest URL; firewalls blocking the querystring-heavy manifest URLs.","solutions":["Request the failing `/__manifest?p=...` URL directly and fix whatever answers it: ensure your server/adapter serves the manifest route, or deploy the generated manifest assets.","Exclude `__manifest` from auth redirects so unauthenticated SPA navigations still discover routes (or accept the error boundary).","If it only happens on stale tabs after a deploy, a hard reload resyncs route discovery.","In tests, make sure any fetch mock returns a 200 with a manifest payload for the manifest URL."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// deploy smoke test: manifest endpoint must be reachable\nconst res = await fetch(`${origin}/__manifest?p=${encodeURIComponent(\"/\")}`);\nif (!res.ok || !res.body) {\n  throw new Error(`route discovery broken: ${res.status}`);\n}","typeGuard":null,"tryCatchPattern":"export function ErrorBoundary() {\n  const error = useRouteError();\n  if (error instanceof Error && /Unable to fetch new route matches/.test(error.message)) {\n    return <Link reloadDocument to=\"/\">Retry</Link>; // full reload retries discovery\n  }\n  throw error;\n}","preventionTips":["Ensure the server/adapter implements the __manifest route before enabling lazy route discovery.","Don't put auth redirects in front of __manifest for SPA flows.","Mock __manifest with a 200 manifest payload in tests."],"tags":["rsc","route-discovery","manifest","lazy","network"],"backgroundTag":"asset-fetch-failed","analyzedSha":"7aea711dd1ae2bc5a076d13ff17291829690fa74","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}