Skip to content

fix(cache): reject unsafe unstable cache fills - #3099

Open
james-elicx wants to merge 8 commits into
codex/cacheability-use-cache-ownershipfrom
codex/cacheability-unstable-cache-upgrade
Open

fix(cache): reject unsafe unstable cache fills#3099
james-elicx wants to merge 8 commits into
codex/cacheability-use-cache-ownershipfrom
codex/cacheability-unstable-cache-upgrade

Conversation

@james-elicx

@james-elicx james-elicx commented Aug 26, 2026

Copy link
Copy Markdown
Member

Follow-up stack 1/2. Exact head: 7ab2b603de888ffc1c009a10e80db8e9f9e8f34c. Base: core #3103 at e2f05581b.

Chain: #3099#3097.

This layer prevents a caught framework-invalid Cache Components execution from being published through unstable_cache():

  • preserves framework dynamic-usage failures on the owning request even when application code catches the immediate error
  • checks the fatal request marker before publishing an unstable_cache() fill and after completed HTML/RSC capture
  • rejects unsafe legacy payloads instead of trusting cached fallback output
  • writes a versioned envelope at the existing physical key, remaining readable by the previous Worker during rollback
  • migrates invalid entries in place on the next safe fill
  • keeps concurrent cold misses independent, matching current Next.js behavior rather than adding request coalescing
  • avoids leaking a fatal marker from standalone/module fallback state into later requests

The built-workerd regression pre-seeds the legacy payload, proves the new Worker rejects it, and verifies the safely replaced payload through the old-Worker reader shape.

Boundary

This layer preserves vinext's existing cold-miss write scheduling: the caller awaits the data-cache write. Current Next.js can attach that write to App request pending revalidations and return the callback result first. Aligning write latency/failure semantics requires broader App Page request-lifecycle ownership and is separate from this cache-publication safety fix; this PR changes only independent callback execution and safe publication.

Next.js references:

Review size

Layer-only diff against #3103: 12 files, +243/-54.

Validation

  • focused cache/runtime tests — 1,374/1,374
  • Cache Components built-workerd E2E — 1/1
  • PPR staged-probe built-workerd E2E — 2/2
  • vp check
  • git diff --check
@james-elicx
james-elicx force-pushed the codex/cacheability-unstable-cache-upgrade branch from 42a924a to 2bfabdc Compare August 26, 2026 18:01
Base automatically changed from codex/cacheability-use-cache-ownership to codex/cacheability-cache-certification August 26, 2026 18:01
@pkg-pr-new

pkg-pr-new Bot commented Aug 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@3099
npm i https://pkg.pr.new/create-vinext-app@3099
npm i https://pkg.pr.new/@vinext/types@3099
npm i https://pkg.pr.new/vinext@3099

commit: 7ab2b60

@james-elicx
james-elicx changed the base branch from codex/cacheability-cache-certification to codex/cacheability-use-cache-ownership August 26, 2026 18:05
@james-elicx
james-elicx force-pushed the codex/cacheability-unstable-cache-upgrade branch from 2bfabdc to 5005ff4 Compare August 26, 2026 18:31
@james-elicx
james-elicx changed the base branch from codex/cacheability-use-cache-ownership to main August 26, 2026 18:31
@james-elicx
james-elicx changed the base branch from main to codex/cacheability-use-cache-ownership August 26, 2026 18:32
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
workers-cache preview production
static-export preview production
web preview production
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 7ab2b60 against base e2f0558 using alternating same-runner rounds. Next.js was unchanged and skipped.

1 improved · 0 regressed · 5 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 142.3 KB 142.3 KB ⚫ -0.0%
Client entry size (gzip) vinext 129.5 KB 129.5 KB ⚫ +0.0%
Dev server cold start vinext 3.33 s 3.27 s 🟢 -1.9%
Production build time vinext 3.70 s 3.74 s ⚫ +1.2%
RSC entry closure size (gzip) vinext 119.0 KB 119.0 KB ⚫ +0.0%
Server bundle size (gzip) vinext 202.3 KB 202.4 KB ⚫ +0.0%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

@james-elicx
james-elicx force-pushed the codex/cacheability-unstable-cache-upgrade branch from 5005ff4 to 49b1839 Compare August 26, 2026 19:33
@james-elicx
james-elicx force-pushed the codex/cacheability-unstable-cache-upgrade branch from 49b1839 to 8905cda Compare August 26, 2026 19:42
@james-elicx
james-elicx force-pushed the codex/cacheability-unstable-cache-upgrade branch from 8905cda to 7ab2b60 Compare August 27, 2026 02:25
@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@ask-bonk

ask-bonk Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

@james-elicx Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@james-elicx
james-elicx marked this pull request as ready for review August 27, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant