withastro/astro · error · Error

Failed to get static paths from the Cloudflare prerender ser

Error message

Failed to get static paths from the Cloudflare prerender server (${response.status}: ${response.statusText}).${details}

What it means

Thrown by the Cloudflare prerenderer when fetching the list of static paths from the local workerd server fails (non-OK response). The `getStaticPaths` method POSTs to the `STATIC_PATHS_ENDPOINT` on the prerender server to discover which routes need prerendering; a failure here means workerd could not enumerate routes.

Source

Thrown at packages/integrations/cloudflare/src/prerenderer.ts:242

			} else {
				throw new Error(
					'Failed to start the Cloudflare prerender server. The preview server did not return a valid address. ' +
						'This is likely a bug in @astrojs/cloudflare. Please file an issue at https://github.com/withastro/astro/issues',
				);
			}
		},

		async getStaticPaths(): Promise<PathWithRoute[]> {
			// Call the workerd endpoint to get static paths
			const response = await fetch(`${serverUrl}${STATIC_PATHS_ENDPOINT}`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
			});

			if (!response.ok) {
				const body = await response.text();
				const details = body ? `\n${body}` : '';
				throw new Error(
					`Failed to get static paths from the Cloudflare prerender server (${response.status}: ${response.statusText}).${details}`,
				);
			}

			const data: StaticPathsResponse = await response.json();

			// Deserialize the routes
			return data.paths.map(({ pathname, route, cacheKey }) => ({
				pathname,
				route: deserializeRouteData(route),
				cacheKey,
			}));
		},

		async render(request, { routeData }) {
			// Serialize routeData and send to workerd
			const body: PrerenderRequest = {
				url: request.url,

View on GitHub (pinned to d081033d5f)

Solutions

  1. Read the `details` body in the error — it carries workerd's error output.
  2. Audit dynamic routes' `getStaticPaths` for code that runs at the top level or uses Node-only APIs.
  3. Ensure all page modules import cleanly under workerd (no `fs`, `child_process`, etc. at module scope).
  4. Run `astro dev` with the adapter to surface the page-level error with a full stack trace.

Example fix

// before — Node-only API at module scope
import { readFileSync } from 'node:fs';
const data = readFileSync('./data.json');
export const GET = () => new Response(data);

// after — read at build time or use a binding
export const GET = async ({ locals }) => {
  const data = await locals.cfContext.env.MY_BUCKET.get('data.json');
  return new Response(data);
};
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure no page module uses Node-only APIs at module scope.
// Audit: grep -rn "from 'node:" in src/pages and src/components used by pages.

Try / catch

try {
  await build();
} catch (e) {
  if (/Failed to get static paths/.test(e.message)) {
    // details body contains workerd's error; inspect dynamic routes' getStaticPaths
  }
  throw e;
}

Prevention

When it happens

Trigger: During build, the POST to `${serverUrl}${STATIC_PATHS_ENDPOINT}` returns non-2xx. The response body (if any) is appended as `details`. Commonly caused by an exception during route enumeration in workerd, a missing getStaticPaths export, or the workerd handler crashing on import.

Common situations: A dynamic route's `getStaticPaths` throws inside workerd. An imported module at the top level of a page fails under workerd (e.g. Node-only API). Bindings missing during the static-paths phase. workerd import resolution differences from Node.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/088b2644b4be9bcd. Report an issue: GitHub.