fix: ignore a malformed ?__draft= or draft cookie (the request gets the release)

Merged
TL
7h ago
+49-11

What

cms.draftPointer(request) now returns null for a ?__draft= value or __deco_draft cookie that parseDraftPointer rejects, the same as when neither is present. The documented wiring (pointer ? cms.forDraft(pointer) : cms.forRelease()) then serves the release for a stray ?__draft=junk link instead of answering 500.

  • A malformed ?__draft= is ignored the way an empty one is: a valid draft cookie still applies.
  • A malformed cookie is null. Before this change only ?__draft=off was filtered out.
  • cms.forDraft("garbage") is unchanged and still returns LOADER_FAILED, as the API reference and the conformance suite document. Only the request-reading path changes.
  • The migration skill's Next.js note now describes the new behavior and keeps the site-side guard only for releases without this fix.

Sites that carry their own parseDraftPointer guard can drop it once they're on a release with this fix. That's a follow-up, and no site is touched here.

Rendered output

A request with a malformed draft value used to get an error. It now renders the release. A valid pointer renders exactly as before.

Tests

  • packages/blocks/src/v8/draft.test.ts: malformed params and cookies give null, a malformed param falls back to a valid cookie, and the end-to-end wiring serves the release revision.
  • bun run test (packages/blocks): all draft, settings, cms and sdk-conformance tests pass. The only failures are unrelated to this change: delivery.cli.test.ts DS-2 also fails on main after #689 (git.ts now runs update-index), and schema.test.ts hit 5s timeouts on a loaded machine. Different files time out on different runs.
  • bun run typecheck (packages/blocks), bun run lint, bun run skills:check.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig


Summary by cubic

cms.draftPointer now treats a ?__draft= value or __deco_draft cookie that doesn't parse as absent, so a malformed pointer renders the release instead of a LOADER_FAILED error. Previously only ?__draft=off was filtered out.

  • A malformed parameter falls back to a valid cookie, like an empty one; a malformed cookie returns null.
  • cms.forDraft("garbage") is unchanged and still fails; only the request-reading path changes.
  • The migration skill's Next.js note now describes the new behavior.