GeezerVison is showing github.com — Fix yarn berry hosted pin of catalog deps (#632) by mikolalysenko · Pull Request #763 · SocketDev/socket-patch
Conversation
LLM Description written by Claude Code:claude-opus-5-5
Fixes #632
Summary
scan --mode hosted now pins yarn berry dependencies declared through a yarn catalog ("left-pad": "catalog:"). Before this, the scan reported redirected: 1, but the next yarn install --immutable failed with YN0028 and a plain yarn install silently installed the unpatched release. This was a regression from #465.
Root cause
Since #465 the hosted yarn berry pin routes the lock entry's descriptors to the hosted tarball through root package.json resolutions, keyed name@npm:<range>. Those keys come from the lock key's expanded ranges in berry_resolutions_pin. Yarn matches resolutions against the manifest descriptor before it expands the catalog, so left-pad@npm:^1.3.0 never matches a dependency declared catalog: or catalog:<named>.
Fix
berry_resolutions_pin reads the .yarnrc.yml catalog: / catalogs: tables through the new berry_catalog_selectors (serde-saphyr). Some catalogs give the package a range that, normalized to yarn's npm: form, is one of the pinned ranges. For each of those, the pin also routes name@catalog: or name@catalog:<named> to the hosted tarball.
- The catalog tables are read as string tables, so an unquoted range keeps its exact text (
1.10 stays 1.10), the way yarn's failsafe schema reads .yarnrc.yml.
- The
npm: selectors stay: transitive dependents still ask for the expanded range, and rollback rebuilds the lock key from them.
- Catalog selectors are derived from the final selector list. So a re-run over a pin written before this fix (lock already keyed by URL, only the
npm: selector) adds the missing catalog selector and leaves the lock alone.
- Rollback needs no change. It already drops every selector routed to the hosted URL and rebuilds the lock key from the
npm: ones; a new test covers this.
- A user-authored
name@catalog: resolution still refuses with redirect_yarn_berry_resolutions_conflict.
- docs/ecosystems.md: the yarn berry hosted notes now describe catalog pins.
- The npm, PyPI and gem wrappers only dispatch to the binary, so they need no change.
Checked by hand with real yarn 4.12.0:
{"left-pad@npm:^1.3.0": X, "left-pad@catalog:": X} installs the patched bytes for a catalog: dependency, and --immutable passes.
- On a project that defines the catalog but declares a plain range, the unused
catalog: selector is harmless: the install gets the patched bytes and --immutable passes.
Per-issue checklist
- Hosted yarn berry pin of a
catalog: dependency keys resolutions by the resolved npm: range, so every yarn install --immutable fails YN0028 (regression from #465) #632, default catalog: yarn_berry_pin_routes_a_default_catalog_dependency (LF, and BOM + CRLF .yarnrc.yml, quoted npm: value)
- Hosted yarn berry pin of a
catalog: dependency keys resolutions by the resolved npm: range, so every yarn install --immutable fails YN0028 (regression from #465) #632, workspace with default + named catalog in one merged entry: yarn_berry_pin_routes_every_catalog_locking_the_entry. Catalogs with another range, another package, or a patch: protocol are ignored.
- Hosted yarn berry pin of a
catalog: dependency keys resolutions by the resolved npm: range, so every yarn install --immutable fails YN0028 (regression from #465) #632, unquoted numeric ranges: yarn_berry_catalog_ranges_keep_their_source_text. 1.10 matches npm:1.10, not npm:1.1. Integer ranges, null entries, other nested keys, a non-table catalog and invalid YAML are all handled.
- Hosted yarn berry pin of a
catalog: dependency keys resolutions by the resolved npm: range, so every yarn install --immutable fails YN0028 (regression from #465) #632, re-run loop: yarn_berry_catalog_pin_rerun_is_stable_and_heals_an_old_pin. A re-run is a no-op, and a pin written before this fix gets healed.
- Hosted yarn berry pin of a
catalog: dependency keys resolutions by the resolved npm: range, so every yarn install --immutable fails YN0028 (regression from #465) #632, rollback: in_process_redirect::yarn_berry_catalog_dependency_is_pinned_and_rolled_back. package.json comes back byte-identical, and the lock gets its npm: key back.
- Hosted yarn berry pin of a
catalog: dependency keys resolutions by the resolved npm: range, so every yarn install --immutable fails YN0028 (regression from #465) #632, real install: e2e_redirect_yarn_berry_build::berry_redirect_catalog_dependency_fresh_checkout_installs (real yarn 4.12.0). A fresh yarn install --immutable --check-cache installs the patched bytes. On yarn < 4.10 the test prints a note and returns, because catalogs don't exist there.
Test evidence
- Red to green: with the catalog lookup disabled, the new core tests fail, and so does the real-yarn e2e (no
left-pad@catalog: selector). With the fix, all pass: cargo test -p socket-patch-core --lib -- yarn_berry gives 102 passed on 9abb2d9.
cargo test -p socket-patch-cli --test in_process_redirect -- yarn_berry: 7 passed.
SOCKET_PATCH_YARN_E2E_REQUIRED=1 cargo test -p socket-patch-cli --test e2e_redirect_yarn_berry_build: 15 passed against real yarn 4.12.0.
cargo test -p socket-patch-cli --lib: 840 passed on 454b068.
- New code is rustfmt-formatted (
cargo fmt --all -- --check also flags pre-existing code on main). cargo clippy --workspace --all-features -- -D warnings is clean.
- An earlier full local
cargo test --workspace --all-features --no-fail-fast run had 14 failures, all from the sandbox. 12 were chmod-based write-failure tests, which can't fail when running as root. 2 were mode_migration_npm fixtures whose registry download rejects the sandbox proxy's TLS certificate. CI runs these for real.
History
🤖 Generated with Claude Code
https://claude.ai/code/session_01DPHxnE5P1rkfCpHFFCwzFR
Note Medium Risk
Changes hosted Yarn Berry lock/manifest rewrite and resolution selector planning; wrong catalog matching could break immutable installs or leave deps unpatched, but behavior is heavily tested and user pins are refused rather than overwritten.
Overview
Fixes #632: Yarn Berry hosted redirects now route catalog: dependencies to the patch tarball, not only the lock’s expanded npm: descriptors.
Yarn Berry hosted pin reads .yarnrc.yml catalog / catalogs tables and adds matching name@catalog: / name@catalog:<named> entries to root package.json resolutions alongside the existing npm: selectors (needed for transitive deps and rollback). Catalog ranges are matched as string source text (e.g. 1.10 ≠ 1.1). Re-runs are stable; older pins that only had npm: selectors get the catalog selector added without touching yarn.lock. User-authored catalog resolutions still fail closed.
Tests & docs: unit tests in redirect/mod.rs, in-process pin/rollback, and a real-yarn e2e for fresh yarn install --immutable with catalog deps; docs/ecosystems.md updated. vex_consumed npm alias tests are adjusted so alias expansion is still exercised after the name-keyed resolver (#605) returns fuller copy sets.
Reviewed by Cursor Bugbot for commit 454b068. Configure here.
Generated by Claude Code
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
A dependency declared "catalog:" in package.json was never patched
by scan --mode hosted: the resolutions entry was keyed by the lock's
expanded npm: range, but yarn matches resolutions before it expands
the catalog. The scan reported success, then yarn install --immutable
failed (YN0028) and a plain yarn install kept the unpatched release.
Also route name@catalog: / name@catalog:<named> for every
.yarnrc.yml catalog that maps the package to a pinned range. A re-run
adds the selector to a pin written by an earlier release.
Fixes #632
Assisted-by: Claude Code:claude-opus-5-5
Add a real-yarn check that a fresh checkout of a hosted-pinned
catalog dependency installs the patched bytes under --immutable,
an in-process scan + rollback round trip, and document catalog
pins in the yarn berry hosted notes.
Assisted-by: Claude Code:claude-opus-5-5
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cargo fmt --all also reformatted 127 files this fix doesn't touch
(main isn't rustfmt-clean). Restore them and the untouched hunks of
the edited files to main, so the PR only carries the catalog fix,
its tests and the docs note.
Assisted-by: Claude Code:claude-opus-5-5
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
One CI check failed on 55dc0cb: native (ubuntu-latest, 2.8.2), the PDM backtest. Only the optional hosted cell failed, on rescanIdempotent. The other 35 PDM cells passed, and so did the other 481 checks.
I don't think this PR caused it:
- The PR only changes yarn berry code:
berry_resolutions_pin and berry_catalog_selectors in patch/redirect/mod.rs, plus yarn tests and docs. The PDM pdm.lock path never calls that code.
- The same job passed on f3f8ca1. That commit has the same fix code; 55dc0cb only reverts formatting in unrelated files.
I don't have a fix to port, because I haven't found a root cause in the PDM path. I've re-run the failed job once. If it fails again, I'll treat it as a real failure and dig in.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Ready for review at 55dc0cb.
- CI: 482/482 checks green on the current head. The earlier PDM
rescanIdempotent failure did not come back on re-run.
- Bugbot: reviewed
55dc0cb and found no issues. There are no unresolved review threads.
- Mergeable: yes, no conflicts with
main.
- For the reviewer: the core change is
berry_catalog_selectors / berry_resolutions_pin in patch/redirect/mod.rs. Catalog selectors are added next to the existing npm: selectors, and rollback is unchanged.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Oct 5, 2026
Resolve the docs/ecosystems.md conflict by keeping both changes: the
yarn catalog routing note from this branch and main's note on how the
re-keyed entry and its bin map are written. Also move the "#404 upgrade
path" doc line back onto its own test; the new catalog test had been
inserted in the middle of that comment.
Co-Authored-By: Claude <[email protected]>
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
One check failed on 2ab819a, the merge of main: composer 2.2.30 / php 8.3 / windows-latest.
This failure isn't caused by this PR. composer_vendor_v_tagged_fresh_checkout_install failed while setting up its fixture, before the test itself ran. The fixture's composer update call timed out reaching packagist:
curl error 28 while downloading https://repo.packagist.org/packages.json: Connection timed out after 10002 milliseconds
The PR's diff against main only touches yarn berry code, and the composer path never calls it. There's no code fix to port, because the problem was reaching the network. I'll re-run the failed job once when the rest of the workflow finishes; GitHub won't allow a re-run while the run is still going.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
berry_catalog_selectors parsed .yarnrc.yml catalogs into serde_json
Values, so an unquoted range like `1.10` became the number 1.1 and
never matched the lock's `npm:1.10`: the `catalog:` selector was
dropped while the pin was still confirmed. Yarn reads .yarnrc.yml with
the failsafe schema, so deserialize the catalog tables as string
tables instead, which keeps each scalar's source text.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DPHxnE5P1rkfCpHFFCwzFR
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
On 2ab819a, coverage and test-release both failed on the same two tests, which this PR doesn't touch:
commands::vex_consumed::tests::hosted_expands_alias_only_copies
commands::vex_consumed::tests::hosted_reuses_expanded_npm_copies_and_merges_alias_variants
main fails them too: I reproduced both failures locally on main at 6811b4e. They broke when #605 and #738 both landed on main. #851 fixes them, so I copied the same test change into this PR as 454b068, and all 840 socket-patch-cli lib tests now pass locally. That commit becomes a no-op once #851 merges.
454b068 sits on top of 9abb2d9, which fixes Bugbot's YAML-number finding. The composer … windows-latest packagist timeout on 2ab819a will be re-tested by this push's CI.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 454b068. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Burn-down agent: labeled Ready for review at 454b068.
- CI: 482 success + 6 skipped, 0 failing; mergeable clean against
main.
- Bugbot:
Cursor Bugbot check passed on 454b068; 0 unresolved review threads.
- Linked issue(s) still open and not fixed on
main.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
Ready for review
Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review
Milestone
No milestone
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.
|