remix-run/react-router · error · Error
No handlers were found for the request: ${url.pathname}${url
Error message
No handlers were found for the request: ${url.pathname}${url.search} What it means
Thrown by the SSR request handler used during `vite preview` (and internal prerender requests). The handler iterates candidate request handlers from the server build; if every handler returns a 404 (or returns nothing), no handler matched the request URL, and the throw surfaces the unmatched `pathname` + `search`. It is the preview-mode equivalent of an unhandled route.
Source
Thrown at packages/react-router-dev/vite/plugin.ts:1720
(a, b) => b.matchDepth - a.matchDepth || a.index - b.index,
)
.map(({ entry }) => entry);
}
for (let { handler } of handlersToTry) {
response = await handler(request, loadContext);
if (response.status !== 404) {
return response;
}
}
if (response) {
return response;
}
let url = new URL(request.url);
throw new Error(
"No handlers were found for the request: " +
url.pathname +
url.search,
);
};
return cachedHandler;
}
return () => {
// Handle SSR requests in preview mode using the built server bundle
previewServer.middlewares.use(async (req, res, next) => {
if (
!ctx.reactRouterConfig.ssr &&
(!process.env.hasOwnProperty("IS_RR_BUILD_REQUEST")
? true
: process.env.IS_RR_BUILD_REQUEST !== "yes")
) {View on GitHub (pinned to 1fd704a7da)
Solutions
- Confirm the path is declared in your routes (`flatRoutes()` glob or manual `route()`).
- Check `basename` in your config matches the URL prefix you are visiting.
- Add a catch-all or resource route for paths external tools hit (e.g. `route("favicon.ico", ...)`).
- Inspect your `serverBundles` function — make sure it does not omit the branch serving this path.
- If prerendering, ensure the path is listed in `prerender` or matched by a route.
Example fix
// before: /favicon.ico returns "No handlers were found"
// after: add a resource route
// app/routes/favicon[.]ico.ts
export const loader = () =>
new Response(favicon, { headers: { "content-type": "image/x-icon" } }); Defensive patterns
Strategy: validation
Validate before calling
// Validate a path is addressable before preview
import { matchRoutes } from "react-router";
const assertRoutable = (routes, pathname) => {
if (!matchRoutes(routes, pathname)) {
throw new Error(`No route matches ${pathname}`);
}
}; Try / catch
try {
await handler(request);
} catch (e) {
if (/No handlers were found/.test(String(e.message))) {
// serve a custom 404 instead of crashing preview
return new Response(notFoundHtml, { status: 404, headers: { "content-type": "text/html" } });
}
throw e;
} Prevention
- Keep a catch-all route (`route("*", ...)`) for unmatched paths.
- Verify `basename` matches your deployment prefix.
- Add resource routes for files bots hit (`favicon.ico`, `robots.txt`).
When it happens
Trigger: Hitting a path during `react-router preview` that is not in the route manifest (e.g. `/favicon.ico` when no route or static file serves it); a misconfigured `basename` so requests resolve against the wrong prefix; a deployed server bundle missing the route because `serverBundles` filtered it out; SPA fallback disabled and the path matches no static asset either.
Common situations: Previewing a prerendered build and visiting a URL that was neither prerendered nor routed; misaligned `basename` between build and preview; tooling/bots requesting `/robots.txt` or `/_health` that have no handler; `serverBundles` accidentally excludes a branch.
Related errors
- Unable to prerender path because it does not match any route
- Unable to define routes with duplicate route id: "${id}"
- Custom Vite manifest paths are not supported
- The "serverBundles" function must return a string
- Prerender (data): Received a ${response.status} status code
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/d8591342e62de90b.
Report an issue: GitHub.