Skip to content

@astrojs/cloudflare: /_image requests break when catch-all routes are combined with prerenderEnvironment: 'node'` #17348

Description

@kitschpatrol

Astro Info

Astro                    v7.0.7
Node                     v26.4.0
System                   macOS (arm64)
Package Manager          pnpm
Output                   static
Adapter                  @astrojs/cloudflare
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

With the Cloudflare adapter configured with prerenderEnvironment: 'node', adding a prerendered catch-all route (src/pages/[...slug].astro) makes every image served through the /_image endpoint return a 500 in astro dev:

[ERROR] Could not import `cloudflare:workers`.
  Error reference:
    https://docs.astro.build/en/reference/errors/failed-to-load-module-ssr/
  Location:
    @astrojs/cloudflare/dist/entrypoints/image-transform-endpoint.js:1:21

Only two ingredients are needed, both in this repo's default config:

  1. prerenderEnvironment: 'node' in the adapter options.
  2. A prerendered catch-all route. Its pattern matches every pathname, including /_image.

The default image service (cloudflare-binding) is already affected — no imageService option is required.

This breaks Starlight. Starlight injects exactly such a route (@astrojs/starlight/routes/static/index.astro, a prerendered /[...slug] catch-all), so any Starlight site using the Cloudflare adapter with prerenderEnvironment: 'node' has every dev-mode image 500 this way. The [...slug].astro in this repo is just a dependency-free stand-in for Starlight's route.

Steps to Reproduce

Clone https://github.com/kitschpatrol/repro-astro-cloudflare-image-dev-error

pnpm install
pnpm dev

Open http://localhost:4321/ — the image is broken. Requesting its /_image URL directly returns a 500 with FailedToLoadModuleSSR.

Then delete src/pages/[...slug].astro and request the same URL: 200, image/webp.

Workaround

Skip the cloudflare:workers-based image endpoint in dev:

const isDev = process.argv.includes("dev");

adapter: cloudflare({
  prerenderEnvironment: "node",
  imageService: isDev ? "passthrough" : "cloudflare-binding",
}),

What's the expected result?

/_image requests in dev return the transformed image (200, image/webp), as they do when either ingredient is removed:

  • Delete src/pages/[...slug].astro → image works.
  • Remove prerenderEnvironment: 'node' → image works.

Link to Minimal Reproducible Example

https://github.com/kitschpatrol/repro-astro-cloudflare-image-dev-error

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P4: importantViolate documented behavior or significantly impacts performance (priority)pkg: astroRelated to the core `astro` package (scope)pkg: cloudflareRelated to the Cloudflare adaptertriage: fix verifiedReporter confirmed the triage bot fix works

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions