remix-run/react-router · error · SingleFetchNoResultError
No result found for routeId "${routeId}"
Error message
No result found for routeId "${routeId}" What it means
In single-fetch mode the server returns a map of per-route results; this error is thrown when the client asks for `result.routes[routeId]` for a route it is revalidating and the entry is `null`/`undefined`. It uses the dedicated `SingleFetchNoResultError` class because the router and middleware logic specifically detect it (e.g., to swap in middleware errors). In practice the server response simply did not include data for a route the client expected to have results for.
Source
Thrown at packages/react-router/lib/dom/ssr/single-fetch.tsx:753
revalidate,
reload,
replace,
status,
} = result.redirect;
throw redirect(location, {
status,
headers: {
// Three R's of redirecting (lol Veep)
...(revalidate ? { "X-Remix-Revalidate": "yes" } : null),
...(reload ? { "X-Remix-Reload-Document": "yes" } : null),
...(replace ? { "X-Remix-Replace": "yes" } : null),
},
});
}
let routeResult = result.routes[routeId];
if (routeResult == null) {
throw new SingleFetchNoResultError(
`No result found for routeId "${routeId}"`,
);
} else if ("error" in routeResult) {
throw routeResult.error;
} else if ("data" in routeResult) {
return routeResult.data;
} else {
throw new Error(`Invalid response found for routeId "${routeId}"`);
}
}
function createDeferred<T = unknown>() {
let resolve: (val: T) => Promise<void>;
let reject: (error: unknown) => Promise<void>;
let promise = new Promise<T>((res, rej) => {
resolve = async (val: T) => {
res(val);
try {View on GitHub (pinned to 6beaca3952)
Solutions
- Hard reload to resync the client's route set with the server after a deploy.
- If you customize `handleRequest` or the single-fetch serialization, make sure every route id the client revalidates appears in the returned routes map.
- Only call `serverLoader()` from routes whose loader actually ran on the server (routes present in the matched request).
- Reproduce with the `.data` request visible in the network tab and compare the route ids in the payload against the ids of matched routes.
Defensive patterns
Strategy: try-catch
Try / catch
export function ErrorBoundary() {
const error = useRouteError();
if (error instanceof Error && error.message.includes("No result found for routeId")) {
return <Link reloadDocument to={location.pathname}>Reload</Link>;
}
throw error;
} Prevention
- Only call serverLoader() from routes included in the current server request.
- Don't filter per-route results out of the single-fetch response in custom servers.
- Hard reload after deploys that change the route tree.
When it happens
Trigger: A clientLoader calling `serverLoader()` for a route that was not part of the server's single-fetch request; version skew where the client revalidates a route the freshly-deployed server no longer runs; a custom server/`handleRequest` that filters which loader results get serialized into the `.data` response; fetcher loads racing a navigation that removed the route.
Common situations: Hitting the error immediately after a deploy that added/removed routes while the browser had the app open; wrapping the server request pipeline with custom logic that drops route results; using `patchRoutesOnNavigation`/lazy route discovery with a server that does not know the new route yet.
Related errors
- SPA Mode: Did you forget to include `<Scripts/>` in your roo
- Unable to decode turbo-stream response
- Invalid response found for routeId "${routeId}"
- You must be using the SSR features of React Router in order
- Unexpected payload type
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/3448da4dfd3764b4.
Report an issue: GitHub.