{"record":{"id":"ea7fb30939f4aec3","repo":"withastro/astro","slug":"failed-to-prerender-request-url-prerendererr","errorCode":null,"errorMessage":"Failed to prerender ${request.url}: ${prerenderError}","messagePattern":"Failed to prerender (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/cloudflare/src/prerenderer.ts","lineNumber":275,"sourceCode":"\t\t\t\turl: request.url,\n\t\t\t\trouteData: serializeRouteData(routeData, trailingSlash),\n\t\t\t\tcollectMetadata,\n\t\t\t};\n\n\t\t\tconst response = await fetch(`${serverUrl}${PRERENDER_ENDPOINT}`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\tredirect: 'manual',\n\t\t\t});\n\n\t\t\t// Check for prerender errors surfaced by the workerd handler via header\n\t\t\t// (the response body may be stripped by the Vite preview server).\n\t\t\t// Only the header marks a failure: pages may intentionally return\n\t\t\t// non-2xx responses while prerendering (e.g. a custom 404 page).\n\t\t\tconst prerenderError = response.headers.get('x-astro-prerender-error');\n\t\t\tif (prerenderError) {\n\t\t\t\tthrow new Error(`Failed to prerender ${request.url}: ${prerenderError}`);\n\t\t\t}\n\n\t\t\tif (collectMetadata) {\n\t\t\t\treturn readFramedPrerenderResponse(response);\n\t\t\t}\n\n\t\t\treturn response;\n\t\t},\n\n\t\tcollectStaticImages:\n\t\t\thasBuildImageService || hasBindingImageService\n\t\t\t\t? async (): Promise<AssetsGlobalStaticImagesList> => {\n\t\t\t\t\t\tconst response = await fetch(`${serverUrl}${STATIC_IMAGES_ENDPOINT}`, {\n\t\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!response.ok) {","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/integrations/cloudflare/src/prerenderer.ts#L257-L293","documentation":"When the Cloudflare adapter prerenders a URL, the workerd handler reports exceptions through an `x-astro-prerender-error` response header, because the Vite preview server may strip the error body. The Node side checks that header first and rethrows the remote error wrapped in this message. Non-2xx statuses alone are not errors here — only the header marks failure, since pages like a custom 404 may intentionally return non-200 while prerendering.","triggerScenarios":"`astro build` with @astrojs/cloudflare prerendering a page whose render throws inside workerd: an uncaught exception in frontmatter, component code, or middleware for that exact request.url.","commonSituations":"Pages using Node-only APIs (fs, crypto internals, native modules) that work in `astro dev` but fail under workerd; a database/NPC client initialized at render time failing in the build sandbox; accessing request headers/env vars missing during build.","solutions":["Read the prerenderError text — it is the original exception message/stack from inside workerd.","Reproduce by running `wrangler dev` against the built worker (or `astro dev` with the adapter) and opening the same URL.","Replace or guard Node-only APIs with web-standard equivalents available in workerd.","Mark the failing page as server-rendered (`export const prerender = false`) if it cannot be built statically.","Provide required environment variables/secrets for the build if the error mentions a missing binding or env var."],"exampleFix":"// before — page crashes under workerd at build\nimport { readFileSync } from 'node:fs';\nconst data = JSON.parse(readFileSync('data.json', 'utf-8'));\n\n// after — static import bundled for any runtime\nimport data from './data.json';","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await build({ root: './' });\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  const m = msg.match(/Failed to prerender (\\S+): (.*)/s);\n  if (m) {\n    console.error(`Page ${m[1]} failed under workerd:`, m[2]);\n    // mark for exclusion or fix, then re-run\n    process.exitCode = 1;\n  } else throw e;\n}","preventionTips":["Develop against the workerd runtime (wrangler dev / adapter dev proxy), not bare Node, when targeting Cloudflare.","Guard environment-specific APIs behind feature checks so prerender falls back gracefully.","Declare pages that need live bindings/secrets as `prerender = false`."],"tags":["cloudflare","prerender","render-error","workerd","build"],"backgroundTag":"prerender-render-failed","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-09-09T03:35:40.650Z","contentChangedAt":"2026-09-09T03:35:40.650Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}