{"record":{"id":"d4b4f33dd04116e0","repo":"remix-run/react-router","slug":"failed-to-patch-routes","errorCode":null,"errorMessage":"Failed to patch routes","messagePattern":"Failed to patch routes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router/lib/rsc/browser.tsx","lineNumber":1103,"sourceCode":"  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) => {\n      (window as WindowWithRouterGlobals).__reactRouterDataRouter.patchRoutes(\n        p.parentId ?? null,\n        [createRouteFromServerManifest(p)],\n      );\n    });\n  });\n}","sourceCodeStart":1085,"sourceCodeEnd":1121,"githubUrl":"https://github.com/remix-run/react-router/blob/7aea711dd1ae2bc5a076d13ff17291829690fa74/packages/react-router/lib/rsc/browser.tsx#L1085-L1121","documentation":"After a successful manifest fetch for lazy route discovery, the decoded payload must have `type: \"manifest\"`; anything else throws this error before routes are patched. The transport succeeded, but the server answered the `__manifest` request with a different payload type (usually a render payload from an HTML fallback or an action/redirect payload).","triggerScenarios":"A custom server routing `__manifest` requests into the SSR/document handler so a render payload comes back; auth redirects rewriting the manifest request into a redirect payload; CDN/edge workers caching a navigation response for the manifest URL; version skew where old manifest URLs hit a new server's fallback.","commonSituations":"Hand-rolled servers that don't special-case `__manifest`; catch-all handlers returning the app shell for every path; test fetch mocks returning the wrong payload type; mid-deploy cache poisoning keyed only by URL.","solutions":["Verify `/__manifest?p=...` returns a manifest payload (type `manifest` with `patches`), not HTML or a redirect.","Fix custom server routing so `__manifest` requests reach the route-discovery handler instead of a document fallback.","Ensure auth guards redirect only document requests, and let manifest requests through or answer them properly.","Purge CDN caches of `__manifest` URLs after each deploy."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// verify the manifest endpoint returns the right payload kind\nconst payload = await res.json();\nif (payload?.type !== \"manifest\") {\n  throw new Error(`__manifest returned type=${payload?.type}`);\n}","typeGuard":"const isManifestPayload = (p: unknown): p is { type: \"manifest\" } =>\n  (p as { type?: string })?.type === \"manifest\";","tryCatchPattern":"export function ErrorBoundary() {\n  const error = useRouteError();\n  if (error instanceof Error && error.message === \"Failed to patch routes\") {\n    return <Link reloadDocument to={location.pathname}>Reload</Link>;\n  }\n  throw error;\n}","preventionTips":["Route __manifest requests to the discovery handler in custom servers, not a document fallback.","Purge CDN caches for __manifest URLs on each deploy.","Keep auth middleware from converting manifest requests into redirects."],"tags":["rsc","route-discovery","manifest","version-skew"],"backgroundTag":"unexpected-response-type","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"}