{"record":{"id":"2a8bbbd21c65607c","repo":"remix-run/react-router","slug":"prerender-request-failed-for-prerenderpath-2a8bbb","errorCode":null,"errorMessage":"Prerender: Request failed for ${prerenderPath}: ${error.message}","messagePattern":"Prerender: Request failed for (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/vite/plugins/prerender.ts","lineNumber":446,"sourceCode":"\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}`,\n    );\n  }\n\n  throw new Error(\n    `Prerender: Request failed for ${prerenderPath}: ${error.message}`,\n  );\n}\n\n/**\n * Issue prerender requests via `node:http` rather than the global `fetch`.\n *\n * Node's built-in `fetch` (undici) keeps a global dispatcher that pools\n * keep-alive sockets. On Windows, exiting the build process with multiple\n * pooled sockets to the Vite preview server still open triggers a libuv\n * assertion (`!(handle->flags & UV_HANDLE_CLOSING)` in `src/win/async.c`)\n * during teardown of the dispatcher's internal async handle. Closing or\n * destroying the dispatcher does not clear the bad state.\n *\n * `node:http` without an explicit Agent closes each connection cleanly, so we\n * use it here to avoid the assertion. Manual redirect handling is preserved.\n */\nasync function nodeHttpFetch(","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-dev/vite/plugins/prerender.ts#L428-L464","documentation":"Thrown by `defaultHandleError` for any prerender request error that is NOT an abort (i.e. `request.signal.aborted` is false). This is the catch-all for exceptions raised by loaders, renderers, or `entry.server.tsx` during the prerender pass. The error message forwards the underlying `error.message` for the failing path.","triggerScenarios":"A loader throws a synchronous or asynchronous exception (network error, parse error, null deref); the renderer throws because of bad data shape; `entry.server.tsx` raises; an upstream dependency errors mid-request without aborting the signal.","commonSituations":"Loaders that throw on malformed data; missing env vars causing `undefined` access; type mismatches between loader output and component props; third-party SDK throwing during build.","solutions":["Reproduce by running `react-router build` with `--logLevel info` to capture the original stack trace from the preview server.","Wrap flaky loader logic in try/catch and return deterministic fallbacks at build time.","Validate the shape of data returned by loaders before rendering.","Provide a custom `handleError` in your prerender config to log full context (Sentry, etc.) instead of only `error.message`."],"exampleFix":"// before: loader throws on missing data\nexport const loader = () => {\n  return JSON.parse(cachedBody).items.map(i => i.name);\n};\n// after\nexport const loader = () => {\n  try {\n    return JSON.parse(cachedBody).items.map(i => i.name);\n  } catch {\n    return [];\n  }\n};","handlingStrategy":"try-catch","validationCode":"// Validate loader output shape before render\nconst assertShape = (data: unknown) => {\n  if (typeof data !== \"object\" || data === null || !(\"items\" in data)) {\n    throw new Error(\"loader returned unexpected shape\");\n  }\n};","typeGuard":null,"tryCatchPattern":"// Provide a custom handleError to log full context\nexport const prerender = {\n  handleError(request, error) {\n    console.error(request.url, error.stack);\n    // swallow during build if acceptable, else rethrow\n  },\n};","preventionTips":["Wrap flaky loader logic in try/catch with build-time fallbacks.","Validate loader output shapes before rendering.","Configure a custom `handleError` to capture full stack traces during the build."],"tags":["prerender","loader","error-handling","build"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}