Repository navigation
Description
Verify latest release
- I verified that the issue exists in the latest pnpm release
pnpm version
12.8.2 and 11.28.3
Which area(s) of pnpm are affected? (leave empty if unsure)
Dependencies resolver
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
With the default minimumReleaseAge, pnpm upgrades a package published in the last day from abbreviated to full metadata and stores the full document in the abbreviated metadata cache without an ETag. The next request that revalidates that cache entry can only send If-Modified-Since, which registry.npmjs.org ignores:
A='application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*'
curl -sD- -o/dev/null -H "accept: $A" https://registry.npmjs.org/is-odd | grep -iE '^(etag|last-modified)'
curl -s -o/dev/null -w '%{http_code}\n' -H "accept: $A" -H 'if-modified-since: <last-modified from above>' https://registry.npmjs.org/is-odd # 200
curl -s -o/dev/null -w '%{http_code}\n' -H "accept: $A" -H 'if-none-match: <etag from above>' https://registry.npmjs.org/is-odd # 304Deterministic repro with a local registry that, like npmjs.org, sends a different ETag per representation and honours only If-None-Match. Three packages were last published an hour ago (inside the release-age window), three a month ago.
pnpm installwith no lockfile. The abbreviated cache entry of a fresh package now holds the full document and no ETag:{"modified":"2026-10-01T19:36:18.173Z"}.- Delete
node_modulesand<cacheDir>/lockfile-verified.jsonl, as after agit pull, and runpnpm install --frozen-lockfile. - Delete
node_modules,pnpm-lock.yamlandlockfile-verified.jsonl, date the metadata cache two days back, and runpnpm installagain.
Packument requests per step, pnpm 12.8.2 (11.28.3 gives the same counts):
| Step | Requests | 304 | Bodies | Body bytes |
|---|---|---|---|---|
| 1. resolve | 9 | 0 | 9 | 18,408 |
| 2. frozen reinstall | 9 | 3 | 6 | 16,476 |
| 3. re-resolve | 9 | 6 | 3 | 14,502 |
Each fresh package costs an extra abbreviated 200 in step 2 (If-Modified-Since only) and an extra full 200 in step 3. The full re-download happens because the abbreviated 200 from step 2 replaced the cached full document, so the release-age upgrade runs again.
Describe the Bug
A minimumReleaseAge upgrade writes the full packument into the abbreviated metadata cache and drops its ETag. #15145 dropped the validator on purpose: the full document's ETag cannot validate an abbreviated request. The cache entry is then left with no ETag at all, so every later revalidation of a recently published package downloads a body from registry.npmjs.org.
Every release I tested is affected: 12.0.0, 12.4.0, 12.5.0, 12.6.0, 12.8.2 and 11.28.3. No release revalidated this entry with a 304. Before #15145, v11 stored the full ETag and sent it with the abbreviated Accept header, which npmjs.org also answers with 200. The write-back to the abbreviated cache came from #11622 (v11) and #11794 (v12).
Expected Behavior
The cache entry keeps the full document's ETag, and pnpm revalidates it as the full document with If-None-Match. The registry answers 304, and the cached document, including its time map, stays as it is.
Which Node.js version are you using?
24.21.0
Which operating systems have you used?
- macOS
- Windows
- Linux
If your OS is a Linux based, which one it is? (Include the version if relevant)
No response
Contributing a fix
- I am working on a fix
Written by an agent (Claude Code, Opus 5.5).
Activity
altaywtf commentedon Oct 1, 2026
I'm working on a fix for this.
Written by an agent (Claude Code, Opus 5.5).
altaywtf commentedon Oct 1, 2026
A fix is ready for review in #16507. CI is green.
Written by an agent (Claude Code, Opus 5.5).
fix(resolving): revalidate release-age upgraded metadata with its ful…
docs(release): curate 11.28.4 and pacquet 12.9.1 release notes
chore(release): 11.28.4, pacquet 12.9.1 (#16567)
fix(deps): update dependencias no-major (#23)
chore(deps): update pnpm to v12.9.0
chore(deps): update pnpm to v12.9.0
chore(deps): update pnpm to v12.9.0
chore(deps): update pnpm to v12.9.0
chore(deps): update pnpm to v12.9.0