Minimal repro for a regression introduced in Astro 6.3.2: Astro action
calls return HTTP 500 in Vite dev mode when using the @astrojs/cloudflare
adapter with prerenderEnvironment: "node" and at least one catch-all
prerendered route. The same action works correctly after a production build and
preview.
Observed error in the Vite terminal:
[ERROR] [vite] Internal server error: fetch failed
at async _Miniflare.dispatchFetch (…/miniflare/src/index.ts:2807:20)
at async file:///…/@cloudflare/vite-plugin/dist/index.mjs:34103:19
| Package | Version |
|---|---|
astro |
6.3.2 |
@astrojs/cloudflare |
^13.5.1 |
npm install
npm run devOpen http://localhost:4321, click Call Action.
Expected: { "message": "Hello, World!" }
Actual: The network request to /_actions/hello returns HTTP 500.
The action works correctly when built and previewed:
npm run build
npm run previewPR #16562 (included in
6.3.2) introduced a new prerender middleware in
vite-plugin-astro-server/plugin.ts. It uses matchAllRoutes() to decide
whether the Node.js prerender handler should intercept a request.
Because spread / catch-all routes like [...page].astro match any pathname
(their pattern covers /_actions/hello, /anything, etc.), the check
matches.some(route => route.prerender) is true for every action request.
The prerender handler therefore fires for actions with { prerenderOnly: true }. Inside handleRequest, devMatch('/_actions/hello') finds no matching
static path in getStaticPaths (action URLs are not page routes), so it
returns handled = false. The middleware then falls through to next(),
which routes the request to @cloudflare/vite-plugin, which dispatches it to
the local workerd/miniflare process via _Miniflare.dispatchFetch. That
dispatch fails with fetch failed.
Before 6.3.2 the prerender middleware forwarded all requests to the Node.js handler unconditionally — actions were handled there and worked. The fix in #16562 changed that unconditional forwarding and unintentionally broke the action path.
| File | Role |
|---|---|
src/pages/[...page].astro |
Catch-all prerendered route — this is the trigger. Without it, matchAllRoutes returns empty for action URLs, the prerender middleware skips, and the bug does not occur. |
wrangler.toml |
Required to fully activate the @cloudflare/vite-plugin / miniflare in dev mode. |
src/actions/index.ts |
Trivial action — any action reproduces the 500. |
astro.config.mjs |
prerenderEnvironment: "node" is required for the separate prerender handler to be registered. |