remix-run/react-router · warning
Detected manifest version mismatch, reloading...
Error message
Detected manifest version mismatch, reloading...
What it means
With lazy route discovery (fog of war), the browser fetches route manifest patches from /__manifest. If a patch response carries a version that differs from the manifest baked into the running page (typical after a new deploy while a tab stayed open), handleClientVersionMismatch stores the new version in sessionStorage (a loop guard — one reload attempt per version) and hard-navigates window.location to errorReloadPath. The never-resolving promise then stalls the initiator so the browser reloads instead of flashing an ErrorBoundary. This is an automatic recovery mechanism, not a crash.
Source
Thrown at packages/react-router/lib/dom/ssr/fog-of-war.ts:285
try {
// This will hard reload the destination path on navigations, or the
// current path on fetcher calls
if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === version) {
// We've already tried fixing for this version, don't try again to
// avoid loops - just let this navigation/fetch 404
console.error(
"Unable to discover routes due to manifest version mismatch.",
);
return true;
}
sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, version);
} catch {
// Session storage unavailable
}
window.location.href = errorReloadPath;
console.warn("Detected manifest version mismatch, reloading...");
// Stall here and let the browser reload and avoid triggering a flash of
// an ErrorBoundary if we threw (same thing we do in `loadRouteModule()`)
await new Promise(() => {
// check out of this hook cause the DJs never gonna re[s]olve this
});
return true;
}
export async function fetchAndApplyManifestPatches(
paths: string[],
errorReloadPath: string | null,
manifest: AssetsManifest,
routeModules: RouteModules,
ssr: boolean,
isSpaMode: boolean,
basename: string | undefined,
manifestPath: string,View on GitHub (pinned to 7aea711dd1)
Solutions
- Treat it as self-healing — no app code change is required; the reload syncs the tab to the new build
- Serve the manifest endpoint (and index HTML) with `Cache-Control: no-store` so patch fetches always hit the current origin build
- Deploy atomically (build to a new directory, swap a symlink) so HTML, assets, and manifest flip versions together
- If it reload-loops, the loop guard logs 'Unable to discover routes due to manifest version mismatch.' — verify all instances serve the same build and purge the CDN cache for /__manifest and HTML
Defensive patterns
Strategy: retry
Try / catch
// framework-internal recovery: one guarded hard reload per manifest version
// (sessionStorage key 'react-router-manifest-version' prevents loops).
// App-level equivalent if you surface your own version banner:
try {
let res = await fetch("/__manifest?version=" + window.__remixManifest.version);
if (!res.ok) location.reload();
} catch { /* offline: retry on next focus */ } Prevention
- Serve /__manifest and index HTML with Cache-Control: no-store so stale versions are never handed out
- Cut over deploys atomically (build dir + symlink swap) instead of overwriting files in place
- Confirm every instance behind the load balancer serves the same build before finishing a rolling deploy
When it happens
Trigger: A navigation or fetcher call to a not-yet-discovered route returns a version-mismatched manifest patch while an errorReloadPath is available — i.e., the server is serving a newer build than the one the current document was rendered from.
Common situations: Users with long-lived tabs across a deploy; CDN or edge caching of /__manifest (or the HTML) serving stale versions; rolling deploys where different instances serve different builds; multiple app versions behind one domain.
Related errors
- Detected a manifest version mismatch during eager route disc
- ${res.status} ${res.statusText}
- Custom Vite manifest paths are not supported
- The `routeDiscovery.manifestPath` config must be a root-rela
- Unable to fetch new route matches from the server
AI-assisted analysis of remix-run/react-router@7aea711dd1 (2026-08-18).
Data as JSON: /api/errors/e5b3263d4c6c8215.
Report an issue: GitHub.