Skip to content

[@astrojs/cloudflare] Prerenderer swallows error details from workerd, returns opaque 500 #15860

@sergioazoc

Description

@sergioazoc

Description

When using injectRoute() in an Astro integration with the @astrojs/cloudflare adapter, the prerenderer fails with a generic 500: Internal Server Error message that provides no actionable information:

prerendering static routes
Failed to get static paths from the Cloudflare prerender server (500: Internal Server Error).
This is likely a bug in @astrojs/cloudflare.

The actual error from the workerd environment (e.g., GetStaticPathsRequired) is available in the response body but is never read or displayed.

Reproduction

  1. Create an Astro project with @astrojs/cloudflare adapter
  2. Create an integration that uses injectRoute() with a dynamic route:
// src/integrations/my-router.ts
import type { AstroIntegration } from 'astro'

export default function myRouter(): AstroIntegration {
  return {
    name: 'my-router',
    hooks: {
      'astro:config:setup': ({ injectRoute }) => {
        injectRoute({
          pattern: '/en/blog/[...slug]',
          entrypoint: './src/views/blog.astro',
          // missing prerender: false — defaults to prerendered
        })
      },
    },
  }
}
  1. The view file has a [...slug] dynamic segment but no getStaticPaths() export (since the intent is SSR)
  2. Run astro build

Expected: A clear error like GetStaticPathsRequired: getStaticPaths() function is required for dynamic routes

Actual: Failed to get static paths from the Cloudflare prerender server (500: Internal Server Error)

Root cause

In dist/prerenderer.js, the getStaticPaths() method checks response.ok but discards the response body:

if (!response.ok) {
  throw new Error(
    `Failed to get static paths from the Cloudflare prerender server (${response.status}: ${response.statusText}).`
  );
}

The workerd server at /__astro_static_paths returns the actual error in the body, but it's never read.

Suggested fix

Read the response body and include it in the error message:

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

The same pattern should be applied to the render() and collectStaticImages() methods for consistency.

Additional context

  • @astrojs/cloudflare version: 13.0.2
  • astro version: 6.0.1
  • The fix above is a one-liner but it saves significant debugging time. I spent a while thinking this was a bug in injectRoute when the actual cause was a missing prerender: false on a dynamic route.

Optional DX improvement

When injectRoute() is called with a pattern containing dynamic segments (like [...slug]) and prerender is not explicitly set, it might be helpful to either:

  • Default dynamic injected routes to prerender: false
  • Or emit a warning suggesting the developer set prerender explicitly

Metadata

Metadata

Assignees

Labels

- P2: has workaroundAn edge case that only affects very specific usage, but has a trivial workaround (priority)pkg: cloudflareRelated to the Cloudflare adapter

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions