GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix yarnrc ${VAR} and YAML setting reads (#1100) by mikolalysenko · Pull Request #1433 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 12, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

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

Fixes #1100

Summary

socket-patch now reads .yarnrc.yml settings the way yarn does. Before this change, a live Plug'n'Play project whose .yarnrc.yml said nodeLinker: "${L:-pnp}" got exit 0 and package_not_installed from agent apply instead of a yarn_pnp_unsupported refusal, and lock-only vendor passed its PnP gate. compressionLevel: "${CL:-0}" was refused as a non-default level, even though yarn reads it as 0.

Root cause

Every .yarnrc.yml setting socket-patch decides on (nodeLinker, compressionLevel, pnpmStoreFolder) went through yarnrc_scalar, a column-0 line scan that returned the literal text after key:. Yarn parses the file as YAML, expands ${NAME} / ${NAME-fallback} / ${NAME:-fallback} in every value (replaceEnvVariables), and matches yarn_* environment keys in any case. So socket-patch and yarn disagreed on:

  • interpolated values (the fail-open regression from Fix yarn PnP detection ignoring nodeLinker (#975, #539) #978 and the false compressionLevel refusal),
  • a quoted key, a value on the next line, or a flow-map document (refused as PnP),
  • yarn_node_linker in lower case (ignored).

Fix

  • New formats::yarn::rc module, a single reader for top-level .yarnrc.yml settings:
    • parses the file as YAML (granit parser, already a dependency) and lets the last occurrence of a key win, as yarn does;
    • a root that isn't a mapping sets nothing;
    • a file that isn't one YAML document falls back to the old line scan;
    • one implementation of yarn's replaceEnvVariables (expand_env), now also used by the npm registry restore (which keeps its rule that it never expands a set variable into a URL).
  • nodeLinker (disk probe, in-memory hosted view, home rc, YARN_NODE_LINKER), the compressionLevel gate and the yarn pnpm-store check all read through it.
  • Fails closed. A linker reference yarn can't expand (unset with no fallback, or expanding to nothing) counts as PnP while a loader exists. The vendor refusal names that value rather than claiming nodeLinker: pnp.
  • Host-independent where the repository isn't on the host. The hosted in-memory view and the compressionLevel gate expand from an empty environment, so a reference passes only through its fallback. A level set in some install environment is already recorded in the lock's cacheKey, which the cache-key gate checks. Agent mode on disk expands from the process environment yarn would run in.
  • Refusals name the value as written, so they never print an expanded environment variable.
  • yarn_node_linker / yarn_rc_filename are matched in any case, in the order yarn uses (last spelling of a setting wins, first spelling of the rc file name).

The TS/Python/gem wrappers only dispatch to the binary, so they need no change.

Test evidence

Each issue row has a regression test. Every one was run red against main's core and green with the fix:

#1100 row Test Red on main
nodeLinker: "${L:-pnp}" / "${L}" with L=pnp / "${L:-node-modules}" with L=pnp, agent apply e2e_safety_yarn_pnp::pnp_loader_under_interpolated_pnp_linker_refuses, pkg_managers::yarnrc_linker_is_read_as_yarn_resolves_it, pkg_managers::yarnrc_linker_references_read_the_environment exit 0 instead of yarn_pnp_unsupported
lock-only vendor PnP gate in_process_vendor::berry_lock_only_pnp_project_refused_up_front ("interpolated pnp" leg) gate passed
quoted key / next-line value / flow map / yarn_node_linker (fail-closed rows) e2e_safety_yarn_pnp::stale_pnp_loader_under_yaml_spelled_linker_applies, rc::yaml_shapes_read_like_yarn, pkg_managers::yarn_env_keys_match_any_case refused as PnP
refusal never prints an expanded variable (review) npm_flavor::tests::unexpandable_linker_refusal_never_prints_an_expanded_variable printed secret${
compressionLevel: "${CL:-0}" (comment) berry_gates::an_interpolated_compression_level_is_read_as_yarn_resolves_it refused

Commands run locally:

  • cargo fmt --all -- --check: clean
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-cli --all-features --test e2e_safety_yarn_pnp: 43 passed
  • cargo test --workspace --all-features: every suite passes except 14 tests across 5 targets (covgap_commands_vendor, e2e_bun_lockb, in_process_redirect, repair, core lib), which fail identically on origin/main in this sandbox: write-failure and permission tests that do not hold when running as root (verified by running each on main)

/code-review high ran on the diff. These findings were fixed: host-env leakage in the memory view and the compression gate, env-key order, yarn_rc_filename case, a root list read as settings, an empty expansion inheriting a parent's linker, the misleading refusal text, and a dead wrapper. Not fixed:

  • The npm registry restore still locates npmRegistryServer / npmScopes with its own line-based YAML path reader; only the expansion is shared now. Moving the nested npmScopes lookup onto a YAML tree is a separate change to the restore path, so it's left as a follow-up.
  • An unexpandable linker is carried as its raw ${…} text rather than a typed state. That keeps the Option<String> linker API every caller uses, and a literal ${ in a linker isn't a value yarn accepts either way, so both read as PnP (fail closed).

🤖 Generated with Claude Code


Note

Medium Risk
Changes Plug'n'Play detection and Berry gate logic for all .yarnrc.yml reads; behavior is intentionally stricter (fail-closed) but could shift outcomes for repos using env interpolation or non-flat YAML.

Overview
Fixes #1100 by replacing the column-0 .yarnrc.yml line scan with a shared formats::yarn::rc reader that parses YAML (quoted keys, block/flow maps, last key wins) and expands ${NAME} / ${NAME-fallback} / ${NAME:-fallback} like Yarn Berry.

PnP and vendor safety: nodeLinker resolution (disk, hosted memory view, env overrides) now uses expanded values. Interpolated linkers that resolve to pnp correctly trigger yarn_pnp_unsupported instead of false package_not_installed; stale loaders under real node-modules configs are ignored. Unexpandable references fail closed as PnP; error text uses the raw rc value so secrets from env are not leaked.

Other call sites: compressionLevel gates and pnpmStoreFolder checks use the same reader (hosted scans use an empty env / YarnEnv::repository_only()). yarn_* env keys are matched case-insensitively with Yarn’s first/last-win rules. Registry URL expansion reuses expand_env with the existing “never expand a set var into a URL” rule.

Regression coverage spans e2e apply, in-process vendor, and unit tests for interpolation, YAML shapes, and refusal messaging.

Reviewed by Cursor Bugbot for commit e90a047. Configure here.


Generated by Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@claude
Start fix for #1100
52a5fe3
Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 12, 2026
Yarn berry PnP refusal misses a live Plug'n'Play project whose .yarnrc.yml sets nodeLinker through ${VAR} interpolation: agent apply exits 0 "not installed" and lock-only vendor passes the PnP gate (regression from #978) #1100
Closed
Claude (claude) added 2 commits October 12, 2026 14:52
@claude
Read .yarnrc.yml settings the way yarn does
a3605fd
Add one reader for top-level .yarnrc.yml settings that parses the
file as YAML (quoted keys, next-line values, flow maps, last key
wins) and expands ${NAME}, ${NAME-fallback} and ${NAME:-fallback}
references exactly as yarn's replaceEnvVariables does. A file that
is not one YAML document falls back to the old column-0 line scan.

Assisted-by: Claude Code:claude-opus-5-5
@claude
Expand ${VAR} in yarnrc linker and cache checks
a72093b
A project whose .yarnrc.yml says nodeLinker: "${L:-pnp}" is a live
Plug'n'Play project to yarn, but socket-patch read the literal text,
so agent apply exited 0 "not installed" instead of refusing PnP, and
lock-only vendor passed its PnP gate. compressionLevel: "${CL:-0}"
was likewise refused as a non-default level.

nodeLinker (disk and in-memory views), compressionLevel and the yarn
pnpm-store check now read the value yarn uses. A reference yarn cannot
expand counts as PnP while a loader exists, and refusals still name
the value as written. yarn_node_linker is read in any case, as yarn
does. The registry reader shares the same expansion code.

Fixes #1100

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 12, 2026
Swarm health manager log #1382
Open
@claude
Keep yarnrc reads host-independent in scans
234d68d
Review follow-ups for the yarnrc reader:

- Hosted in-memory scans and the compressionLevel gate no longer
  expand ${VAR} from the scanning host's environment, so the same
  repository gets the same answer on every machine.
- yarn_node_linker and yarn_rc_filename are matched in any case,
  in the order yarn uses.
- A linker that expands to nothing no longer inherits a parent rc's
  value, and a .yarnrc.yml whose root is a list sets nothing.
- The vendor PnP refusal names an unexpandable linker instead of
  claiming nodeLinker: pnp.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 12, 2026 15:30
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 12, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

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.

All reactions
Tanmay182003
Tanmay Singla (Tanmay182003) reviewed Oct 12, 2026
View reviewed changes
Comment thread crates/socket-patch-core/src/vendor/npm_flavor.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Never print an expanded var in linker refusal
e90a047
A checked-in .yarnrc.yml like nodeLinker: "${NPM_TOKEN}${" expanded
the token, kept the trailing "${", and was then refused as PnP with
the expanded value (the token) in the vendor refusal text. A linker
that still holds a literal "${" after expansion now falls back to
the text as written, so refusals only ever name unexpanded values.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 12, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 e90a047. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Tanmay182003
Tanmay Singla (Tanmay182003) approved these changes Oct 12, 2026
View reviewed changes
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 12, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

Final reviewer: approved on head e90a047, ci-ok and clippy green, no open threads, mergeable. Sent to the merge queue (squash auto-merge).


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Merged via the queue into main with commit 3b12cb7 Oct 12, 2026
54 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-yarnrc-setting-interpolation branch October 12, 2026 16:58
This was referenced Oct 12, 2026
CI flake: coverage job fails intermittently in vendor / in_process_edge_cases #1416
Closed
chore(release): bump to 5.0.1 with release notes #1446
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@Tanmay182003 Tanmay Singla (Tanmay182003) Tanmay182003 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Yarn berry PnP refusal misses a live Plug'n'Play project whose .yarnrc.yml sets nodeLinker through ${VAR} interpolation: agent apply exits 0 "not installed" and lock-only vendor passes the PnP gate (regression from #978)

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@mikolalysenko @Tanmay182003 @claude
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.