{"record":{"id":"64f8ece20f44671c","repo":"withastro/astro","slug":"the-prerender-server-responded-response-status","errorCode":null,"errorMessage":"the prerender server responded ${response.status} ${response.statusText}${details}","messagePattern":"the prerender server responded (.+?) (.+?)(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/cloudflare/src/prerenderer.ts","lineNumber":148,"sourceCode":"\tsourcePath: string | undefined,\n): Promise<void> {\n\tconst response = await fetch(createImageTransformUrl(serverUrl, originalPath, transform), {\n\t\tmethod: 'POST',\n\t\t// Remote images have no local original; the worker fetches those itself.\n\t\t...(sourcePath\n\t\t\t? {\n\t\t\t\t\tbody: Readable.toWeb(createReadStream(sourcePath)) as unknown as BodyInit,\n\t\t\t\t\t// Required by Node's fetch whenever the body is a stream.\n\t\t\t\t\tduplex: 'half',\n\t\t\t\t}\n\t\t\t: {}),\n\t} as RequestInit);\n\n\tif (!response.ok || !response.body) {\n\t\t// The body can be a full error page, so keep only enough of it to be useful.\n\t\tconst body = (await response.text().catch(() => '')).replace(/\\s+/g, ' ').trim();\n\t\tconst details = body ? `: ${body.slice(0, 200)}` : '';\n\t\tthrow new Error(\n\t\t\t`the prerender server responded ${response.status} ${response.statusText}${details}`,\n\t\t);\n\t}\n\n\tconst outputPath = join(fileURLToPath(clientDir), finalPath);\n\tawait mkdir(dirname(outputPath), { recursive: true });\n\t// `fetch` types the body as the DOM `ReadableStream`, which is structurally\n\t// identical to but nominally distinct from the `node:stream/web` one.\n\tconst body = response.body as unknown as NodeReadableStream<Uint8Array>;\n\tawait pipeline(Readable.fromWeb(body), createWriteStream(outputPath));\n}\n\n/**\n * Creates a prerenderer that uses Cloudflare's workerd runtime via a preview server.\n * This allows prerendering to happen in the same runtime that will serve the pages.\n */\nexport function createCloudflarePrerenderer({\n\troot,","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/integrations/cloudflare/src/prerenderer.ts#L130-L166","documentation":"During `astro build`, the Cloudflare adapter prerenders pages by fetching them from a local workerd-backed Vite preview server it starts on a random port. If that server answers with a non-OK status or no body, the build fails here; the message embeds the HTTP status and up to 200 characters of the (whitespace-collapsed) response body to expose the underlying failure. This is the Node-side mirror of a render failure that happened inside workerd.","triggerScenarios":"Building with @astrojs/cloudflare while prerendering is enabled, and a page/middleware throws inside the workerd runtime, a route 404s on the internal server, or the response stream aborts so `response.ok` is false or `response.body` is null.","commonSituations":"A page works in `astro dev` (Node) but uses an API unavailable in workerd (fs, native modules, Node streams); middleware crashing for the prerendered route; a dependency with workerd-incompatible code paths; version mismatch between astro and the adapter.","solutions":["Read the body snippet in the message — it usually contains the real stack trace from inside workerd.","Reproduce locally with `wrangler dev` (or `astro dev` with the adapter's platform proxy) and open the failing page to get the full error.","Search the failing page, its layout, and middleware for Node-only APIs and replace them with runtime-agnostic or web-standard alternatives.","If the page is not meant to be prerendered, set `export const prerender = false` on it.","Update @astrojs/cloudflare and astro to matching latest versions."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"import { build } from 'astro';\ntry {\n  await build({ root: './', logLevel: 'info' });\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  // messages embed 'the prerender server responded <status>' plus up to 200 chars of body\n  if (msg.includes('prerender server responded')) {\n    console.error('Workerd-side render failure — body snippet:', msg);\n    process.exitCode = 1;\n  } else throw e;\n}","preventionTips":["Run pages through `wrangler dev` (or the adapter's dev platform) before build so workerd incompatibilities surface early.","Avoid Node-only APIs in prerendered pages/layouts/middleware.","Keep astro and @astrojs/cloudflare versions upgraded together."],"tags":["cloudflare","prerender","build","workerd","fetch"],"backgroundTag":"prerender-request-failed","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}