Skip to content

Read berry restore registry like yarn does (#1017) - #1323

Merged
Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
agent/v5-berry-registry-sources
Oct 10, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 4 commits into
mainfrom
agent/v5-berry-registry-sources

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #1017

Summary

Hosted yarn berry rollback, remove and the takeover restore now read each package's registry the way yarn resolves it. Before, they only read the project .yarnrc.yml's top-level npmRegistryServer. A mirror configured anywhere else was ignored: the restore read npmjs (or SOCKET_NPM_REGISTRY), wrote a bare name@npm:<v> locator with no warning, and the next cold yarn install --immutable failed YN0035 … 404 against the mirror.

The registry sources the restore now reads:

  • a scoped package's npmScopes.<scope>.npmRegistryServer (the scope's own server wins; a scope without one falls through to the default server)
  • YARN_NPM_REGISTRY_SERVER
  • npmRegistryServer from the closest .yarnrc.yml (or YARN_RC_FILENAME) that sets it: the lock's directory, then every parent directory up to the filesystem root, then the home directory
  • ${VAR-default} and ${VAR:-default} in those values: a reference to an unset variable is read as its default, as yarn's replaceEnvVariables reads it. A reference to a variable that is set is never expanded, because a checked-in rc file must not choose which of the process's variables (a token, say) lands in a URL the restore requests and may print. It gets the fallback below instead, like the Bun and pnpm settings readers (Bugbot security review).

When yarn's registry can't be known, the restore falls back to the default registry and now warns upstream_registry_fallback instead of staying silent. That covers a reference to an unset variable with no default (yarn itself refuses to run then), a reference to a set variable (see above) and an npmScopes written as a flow mapping, which this reader doesn't follow.

The per-package registry also decides whether the restored locator keeps its ::__archiveUrl= binding. Before, a scoped package was compared against the top-level registry.

Root cause

berry_lookup_registry and restore_berry (crates/socket-patch-core/src/patch/redirect/upstream/npm.rs) read only the project rc's top-level key. They returned the default registry for every scoped name once an npmScopes block existed, and they ignored env, parent-directory rc files, the home rc and interpolation.

The fix

  • BerryRegistrySettings::read collects the rc chain as yarn finds it (lock directory → ancestors → home, closest first, home skipped when it is already in the chain) plus YARN_NPM_REGISTRY_SERVER.
  • berry_lookup_registry(rcs, env, name, var) is a pure resolver. It reads nested block mappings with a small path reader (yaml_path_value) and expands references with yarn_expand_env.
  • restore_berry resolves once per package name, passes the result to fetch_dists_on and berry_registry_locator, and warns on Err.

YARN_NPM_SCOPES (an env override of the whole scope map) isn't read. The issue's cells don't use it, and yarn's env form for a map setting is unusual.

Tests (red → green)

Issue cell Test
env YARN_NPM_REGISTRY_SERVER, parent-dir rc, ~/.yarnrc.yml (project outside home), ${VAR:-mirror} in the project rc: rollback keeps the mirror's ::__archiveUrl= binding byte-exactly crates/socket-patch-cli/tests/in_process_redirect.rs::yarn_berry_rollback_reads_the_registry_from_every_yarn_source
a registry yarn can't resolve warns upstream_registry_fallback …::yarn_berry_rollback_warns_when_the_registry_cannot_be_known
npmScopes scoped / unscoped / scope without a server, scope vs env vs rc precedence, layered rc files, flow-style refusal npm.rs unit berry_reads_the_registry_from_every_yarn_settings_source
interpolation semantics (${A-d}, ${A:-d}, empty vs unset, unset with no default, a set variable refused) npm.rs unit berry_registry_values_expand_env_references_like_yarn
BOM handling kept npm.rs unit berry_scopes_probe_reads_past_one_bom_only (updated: a scoped name now gets its scope's registry, which the old test pinned as the default registry)

Red: with the resolver cut back to the old sources (project rc only, no env), the CLI cell fails at Env: rollback keeps the mirror's __archiveUrl binding. Green with the fix. The #908 control (yarn_berry_rollback_reads_the_tarball_from_the_project_registry) still passes.

CLI_CONTRACT.md documents the sources and the new fallback cases.

Commands run (local, macOS)

  • cargo fmt --all -- --check (files touched by this PR)
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-core --no-fail-fast: 0 failures
  • cargo test -p socket-patch-cli --lib --test in_process_rollback_hosted --test in_process_redirect --test mode_migration_npm --test in_process_vendor: 915 + 139 + 35 + 131 + 21 passed, 0 failed

Overlap: open PR #1283 (Bun user registry config) also edits upstream/npm.rs, in the Bun section only. No textual overlap is expected beyond imports.

🤖 Generated with Claude Code


Note

Medium Risk
Changes upstream lockfile restore behavior for Yarn Berry hosted pins; incorrect resolution could still produce wrong tarball URLs, though fallbacks are now warned and heavily tested.

Overview
Fixes hosted Yarn Berry rollback/remove restoring lock entries against the wrong npm registry when the mirror is not on the project .yarnrc.yml top-level npmRegistryServer.

Registry resolution now mirrors Yarn: scoped npmScopes.<scope>.npmRegistryServer, then YARN_NPM_REGISTRY_SERVER, then the nearest .yarnrc.yml in the lock directory → parents → home, with ${VAR} / ${VAR:-default} expansion. Each package’s resolved registry drives version-document fetches and whether the restored locator keeps ::__archiveUrl=. When the registry cannot be determined (unset env ref with no default, flow-style npmScopes), restore falls back to the default registry and emits upstream_registry_fallback instead of silently writing a bare locator that breaks immutable installs against mirrors.

CLI contract and integration/unit tests cover env, parent/home rc, interpolation, and the new warning path.

Reviewed by Cursor Bugbot for commit d1221ab. Configure here.


Generated by Claude Code

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Hosted yarn berry rollback, remove and the takeover restore read
only the project .yarnrc.yml's top-level npmRegistryServer. A
mirror set through npmScopes, YARN_NPM_REGISTRY_SERVER, a
parent-directory or home .yarnrc.yml, or a ${VAR:-default} value
was ignored. The restore then dropped the mirror's __archiveUrl
binding without a warning, and the next cold immutable install
failed YN0035.

The restore now resolves each package's registry the way yarn
merges its settings, and warns upstream_registry_fallback when
the registry cannot be determined.

Fixes #1017

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) changed the title Fix berry restore registry lookup sources (#1017) Read berry restore registry like yarn does (#1017) Oct 9, 2026
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 9, 2026 17:57
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review

Comment thread crates/socket-patch-core/src/patch/redirect/upstream/npm.rs

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d1221ab. Configure here.

Comment thread crates/socket-patch-core/src/patch/redirect/upstream/npm.rs
Comment thread crates/socket-patch-cli/tests/in_process_redirect.rs
A checked-in .yarnrc.yml could name any variable of the
socket-patch process (a token) in npmRegistryServer. The restore
would then request, and on a failed lookup print, a URL carrying
it. A reference to a variable that is set is now treated as an
undeterminable registry. The restore falls back to the default
registry with upstream_registry_fallback, as the Bun and pnpm
settings readers already do. An unset variable's default is still
read the way yarn reads it.

The hosted-unwind test runner also clears YARN_NPM_REGISTRY_SERVER
and YARN_RC_FILENAME, so an ambient value can't steer the fixtures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 9, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review at e5e3b494dcef.

  • CI: required checks ci-ok and clippy green; 7 check suites succeeded. 1 superseded workflow run(s) show as cancelled; the required gates passed on this head.
  • Mergeable against main, no CHANGELOG.md change.
  • Bugbot reviewed this head; no unresolved review threads.

Labeled Ready for review by the burn-down agent. Slack announcement pending (connector unavailable this run).


Generated by Claude Code

Resolve conflicts with #1131 (restored berry entry takes the registry's
bin spelling back): keep the per-package registry lookup for the locator
and feed it to the bin re-render; keep both rollback tests; merge the
CLI_CONTRACT npm-family paragraph (berry registry chain + #1131 + #1276
Bun user config) and take main's uv override wording.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merged via the queue into main with commit 92e001a Oct 10, 2026
53 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/v5-berry-registry-sources branch October 10, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

2 participants