Repository navigation
Keep Deno KV caches per V8 release branch - #15180
Merged
Merged
Conversation
Deno 2.9 writes V8 serializer format 16 (2.7 writes 15), and an older V8 rejects newer formats, so a Quarto on Deno 2.9 poisons the shared sass.kv for every older Quarto on the machine (RangeError: could not deserialize value). Open the store and write the compiled CSS under v8-<major>.<minor> inside the requested cache dir; the untagged files are never touched, so older versions keep working. The registry stays keyed by the requested path, so cleanup passes that key explicitly (#14594, #13955).
Same cause as the Sass cache: Deno 2.9 writes V8 serializer format 16 and an older V8 rejects it, so a shared .quarto/project-cache/deno-kv-file written by a newer Quarto breaks every older Quarto on the project. Put the index and the content-addressed files under project-cache/v8-<major>.<minor>. The untagged files stay untouched for older versions.
The new cache tests write and read legacy sentinel files and open a KV store to prove the untagged stores stay untouched.
clear() passed each index entry's value to join() as if it were a hash string, but disk entries store {hash, type} and immediate entries store {value, type}. join() threw "Path must be a string", so any populated cache made clear() fail.
The only caller is init() when the stored cache version is unknown, i.e. a cache written by a newer Quarto. That is the cross-version case this branch is about: an older Quarto would crash there instead of clearing the cache. The bug dates from the cache's introduction in 60294d0.
clear() now removes the hash file only for disk entries, and drops immediate entries from the index alone. It uses safeRemoveSync because entries with identical content share one hash file, so the second removal finds it gone. That replaces a raw Deno call, so the src count in the runtime boundary baseline drops by one.
Collaborator
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
1 of 5 tasks
cderv
added a commit
that referenced
this pull request
Oct 23, 2026
#15180 merged without a changelog entry.
cderv
added a commit
that referenced
this pull request
Oct 23, 2026
#15183) The PR-mode runtime boundary check compared the merge result only with the base branch's baseline, so a PR that had already run --update-baseline --accept-increase still got a warning for each new call and the maintainer block. See #15180, where six new Deno calls were accepted in the PR's baseline and still reported as pending. - Read the working-tree baseline in PR mode. An increase the PR raised there, and that the merge result does not exceed, is a notice listed under "Accepted in this PR". - Keep the warnings when the base baseline has room the PR did not take, or when the merge result is now above the accepted count. - Leave errors for Deno APIs that src/deno_ral replaces unchanged. Related to #15153
cderv
added a commit
that referenced
this pull request
Oct 23, 2026
…absorb Two cache changes landed or are landing ahead of the plans that assume they own that code. #15180 keeps Deno KV stores in a v8-<branch> directory and exports v8Branch from platform.ts, because Deno 2.9 writes V8 values Deno 2.7 cannot read. The #15119 fix creates src/deno_ral/kv.ts first, with damage classification that PR 18 has to keep. The plans stay unedited until their step 0, so the findings go in as "Open decisions with an owner" rows naming PRs 18, 19, 26, 27b and 30. The store-name convention and the platform.ts/kv.ts vocabulary state the per-V8-branch rule now, since every later plan reads them. docs: runtime migration, keep PR 18's list() change and move the KV damage tests to PR 30 Dropping PR 18 Task 2 Step 2 whole would also drop the list({ prefix: [] }) to list([]) change clear() needs once the index is a KeyValueStore, so the step now shrinks to that change and keeps the clear() body #15180 shipped. The PR 26 row asked for known-failures entries for the Deno KV damage tests, but its node-unit job runs only tests/unit/ral/ and rejects an entry for a file that did not run. Those tests first meet Node in PR 32's full suite, after PR 30 removes Deno KV, so PR 30 replaces or deletes them instead.
This was referenced Oct 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deno 2.9 writes V8 serializer format 16 where 2.7 writes 15, and an older V8 rejects newer formats. Once a Quarto on Deno 2.9 touches the shared
sass.kvor a project's.quarto/project-cache/deno-kv-file, every older Quarto on the machine fails to render withRangeError: could not deserialize valueuntil the cache is deleted. The reverse direction is fine, 2.9 reads 2.7 data. This has to land before the Deno bump in #15157 (#15152), and in any 1.10.x backport of it.Released Quarto cannot be fixed on its read side, so the new Quarto must never write a store that older versions open. Both caches now live in a
v8-<major>.<minor>subdirectory, taken fromDeno.version.v8, holding the KV file and its data files. A separate index in the same directory would let two versions overwrite each other's<hash>.cssor content files. Untagged stores are left untouched, so older versions keep using them.Alternatives considered: treating a deserialize error as a cache miss only helps versions that already contain the change, and tagging by Deno version instead of V8 branch would invalidate the cache on every patch bump. Old tagged directories are not pruned. This is an interim measure until the cache moves off Deno KV in the runtime migration.
Project cache
clear()clear()passed each index entry's value tojoin()as if it were a hash, but disk entries store{hash, type}and immediate entries store{value, type}, so any populated cache threwPath must be a string. Its only caller isinit()when the stored cache version is unknown, which is exactly the cache written by a newer Quarto, so it is reachable from this change's scenario. It now removes the hash file only for disk entries, withsafeRemoveSyncsince entries with identical content share one file.Checklist
I have (if applicable):
AI-assisted PR
Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.
Related to #15157, #15152