{"record":{"id":"42bddb2cf447683e","repo":"remix-run/react-router","slug":"prerender-request-failed-for-prerenderpath","errorCode":null,"errorMessage":"Prerender: Request failed for ${prerenderPath}: ${response.status} ${response.statusText}","messagePattern":"Prerender: Request failed for (.+?): (.+?) (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/vite/plugins/prerender.ts","lineNumber":424,"sourceCode":"            },\n          },\n        };\n      },\n    },\n    configResolved(resolvedConfig) {\n      viteConfig = resolvedConfig;\n    },\n  };\n}\n\nasync function defaultPostProcess(\n  request: Request,\n  response: Response,\n): Promise<PrerenderFile[]> {\n  const prerenderPath = new URL(request.url).pathname;\n\n  if (!response.ok) {\n    throw new Error(\n      `Prerender: Request failed for ${prerenderPath}: ${response.status} ${response.statusText}`,\n    );\n  }\n\n  return [\n    {\n      path: `${prerenderPath}/index.html`,\n      contents: await response.text(),\n    },\n  ];\n}\n\nfunction defaultHandleError(request: Request, error: Error): void {\n  const prerenderPath = new URL(request.url).pathname;\n\n  if (request.signal?.aborted) {\n    throw new Error(\n      `Prerender: Request timed out for ${prerenderPath}: ${error.message}`,","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-dev/vite/plugins/prerender.ts#L406-L442","documentation":"Thrown by `defaultPostProcess` (the plugin's built-in post-processor) when the prerender request's response is not `response.ok` (i.e. status outside 200–299). Unlike the typed `metadata` post-processor in `plugin.ts`, this default handler is used when no custom `postProcess` is configured; it cannot interpret non-200 bodies, so it aborts with the status code and reason.","triggerScenarios":"A prerendered route returns 4xx/5xx from the preview server during the prerender pass; the route's loader throws; `entry.server.tsx` returns an error response; a resource route that 404s during prerender.","commonSituations":"CI build where the loader fails on missing env data; a route that conditionally returns 404; preview server misconfigured (wrong port/hostname) so requests 502.","solutions":["Reproduce by running `react-router build` then `react-router preview` and fetching the printed path.","Make the loader/renderer return 200 for prerendered paths at build time.","Implement a custom `postProcess` if you need to tolerate non-200 (e.g. write the error page to disk intentionally).","Remove the path from `prerender` if it cannot succeed at build time."],"exampleFix":"// before: loader returns 404 for a prerendered path\nexport const loader = ({ params }) => {\n  if (!params.slug) return new Response(null, { status: 404 });\n};\n// after\nexport const loader = ({ params }) => {\n  return json({ slug: params.slug ?? \"home\" });\n};","handlingStrategy":"try-catch","validationCode":"const assertOk = (res: Response, path: string) => {\n  if (!res.ok) throw new Error(`prerender ${path} -> ${res.status}`);\n};","typeGuard":null,"tryCatchPattern":"try {\n  await prerender(cfg);\n} catch (e) {\n  if (/Prerender: Request failed for/.test(String(e.message))) {\n    // log full context, optionally skip the path and continue\n    console.warn(e.message);\n  } else throw e;\n}","preventionTips":["Loaders for prerendered paths must return 2xx at build time.","Provide a custom `postProcess` to tolerate intentional non-200 paths.","Reproduce failures locally via `react-router preview` before pushing."],"tags":["prerender","post-process","build","loader"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}