Skip to content

fix(pages): deferred props, action responses and dev rescan errors - #517

Merged
Brooooooklyn merged 1 commit into
mainfrom
fix/pages-ssr-batch
Oct 21, 2026
Merged

Brooooooklyn merged 1 commit into
mainfrom
fix/pages-ssr-batch

Conversation

@Brooooooklyn

Copy link
Copy Markdown
Member

Fixes six bugs in Pages SSR: deferred props, action responses, and dev rescans.

Bug Before Now
A page scan error during a dev rescan (e.g. layout: docs before _layouts/docs.* exists) unhandled rejection, void dev exits the error is logged and the last good scan is kept; the next change rescans
A deferred value whose object has a key named like another deferred prop the value lands in that other prop, and its own prop never resolves a group resolves only its own keys
A deferred resolver that throws, in prefetch or prerender silent null, baked into _void/pages/*.json sent as deferredErrors, and the client rejects that prop as it does when streaming
A deferred resolver that returns undefined, on client navigation stays loading forever resolves to null, as on a full page load
A loader that returns a redirect or 404 after an action page renders with {} props the loader's Response is returned, as on a GET
A 400 from an action that is not from withValidator a text body becomes a 500; a JSON body is swallowed passed through unchanged; only an issues body becomes field errors

How

protocol.ts         runLoader(): one rule for GET and post-action loader runs
                    prefetch: deferredErrors per failed group; undefined → null
                    NDJSON: data ?? null
                    400: clone().json() → issues[] ? field errors : pass through
navigation-engine   resolveGroup: one key → raw value; several keys → value[key]
                    setup(resolved): a key whose group is in deferredErrors is rejected
                    retainOnly keeps full groups, so a preserved part of a group still splits correctly
islands-plugin +    rescan errors are handled; the adapter pages plugin logs them once
4 adapter plugins

The deferred rule is the one the server's prefetch path and the docs ("Grouped Deferred Props") already use.

Tests

  • New tests: 17, in pages-client, pages-protocol, the new pages-islands-rescan, and the react/vue/svelte/solid plugin-pages tests. All 17 fail on main.
  • Unit tests: the pages, prerender and island files in void pass (326 tests), as do all the adapters' unit tests.
  • Browser tests: React 44/44 and Vue 30/30.
  • Checks: typecheck for void and the 4 adapters, lint and format are clean.

🤖 Generated with Claude Code

- Dev: a page scan error during a rescan is logged and the last good scan
  is kept, instead of an unhandled rejection that stops the dev server.
- A deferred group resolves only its own keys: a one-key group takes the
  raw value, a larger group takes each key from the object. A value whose
  object has a key named like another deferred prop no longer lands there.
- Prefetch and prerender payloads send a failed deferred group as an error
  that the client rejects, instead of a silent null.
- A deferred resolver that returns undefined resolves to null on client
  navigation, as it already did on a full page load.
- After an action, a loader that returns a redirect or error Response
  answers with that Response, as on a GET, instead of rendering {} props.
- Only a withValidator issues body in a 400 becomes field errors. Other
  400 responses from an action pass through unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T04:06:15.150036Z b82fcfa Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://fix-pages-ssr-batch-void-cloud.voidzero-docs.workers.dev (commit b82fcfa)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://67a45835-void-cloud.voidzero-docs.workers.dev b82fcfa 2026-10-21T04:04:58.588Z Visit the dashboard ↗

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: b82fcfaede

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Brooooooklyn
Brooooooklyn merged commit d8618c8 into main Oct 21, 2026
20 checks passed
@Brooooooklyn
Brooooooklyn deleted the fix/pages-ssr-batch branch October 21, 2026 04:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant