remix-run/react-router · error · Error
Failed to patch routes
Error message
Failed to patch routes
What it means
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).
Source
Thrown at packages/react-router/lib/rsc/browser.tsx:1103
let response = await fetchImplementation(new Request(url, { signal }));
if (
clientVersion !== undefined &&
response.status === 204 &&
response.headers.has("X-Remix-Reload-Document")
) {
await handleClientVersionMismatch(true, clientVersion, errorReloadPath);
return;
}
if (!response.body || response.status < 200 || response.status >= 300) {
throw new Error("Unable to fetch new route matches from the server");
}
let payload = (await createFromReadableStream(response.body, {
temporaryReferences: undefined,
})) as RSCPayload;
if (payload.type !== "manifest") {
throw new Error("Failed to patch routes");
}
// Track discovered paths so we don't have to fetch them again
paths.forEach((p) => addToFifoQueue(p, discoveredPaths));
let patches = await payload.patches;
// Without the `allowElementMutations` flag, this will no-op if the route
// already exists so we can just call it for all returned patches
React.startTransition(() => {
patches.forEach((p) => {
(window as WindowWithRouterGlobals).__reactRouterDataRouter.patchRoutes(
p.parentId ?? null,
[createRouteFromServerManifest(p)],
);
});
});
}View on GitHub (pinned to 7aea711dd1)
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.
Defensive patterns
Strategy: fallback
Validate before calling
// verify the manifest endpoint returns the right payload kind
const payload = await res.json();
if (payload?.type !== "manifest") {
throw new Error(`__manifest returned type=${payload?.type}`);
} Type guard
const isManifestPayload = (p: unknown): p is { type: "manifest" } =>
(p as { type?: string })?.type === "manifest"; Try / catch
export function ErrorBoundary() {
const error = useRouteError();
if (error instanceof Error && error.message === "Failed to patch routes") {
return <Link reloadDocument to={location.pathname}>Reload</Link>;
}
throw error;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to fetch new route matches from the server
- Unexpected payload type
- Custom Vite manifest paths are not supported
- The "@vitejs/plugin-rsc" plugin should be placed after the R
- When using the React Router `basename` and the Vite `base` c
AI-assisted analysis of remix-run/react-router@7aea711dd1 (2026-08-18).
Data as JSON: /api/errors/d4b4f33dd04116e0.
Report an issue: GitHub.