Repository navigation
Vendored yarn classic wiring breaks every install run from a workspace member directory: yarn resolves the file:./.socket/vendor/… tarball against the member dir #691
Description
[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).
Summary
In a yarn classic workspaces project, vendored mode rewrites the target's yarn.lock block to resolved "file:./.socket/vendor/npm/<uuid>/<pkg>.tgz#<sha1>". Yarn classic resolves a relative file: tarball in resolved against the current working directory, not the workspace root that holds yarn.lock. So as soon as the project is vendored, every yarn command run from a member directory fails on a cold cache:
cd packages/b && yarn install --frozen-lockfileyarn --cwd packages/b installyarn workspace b add <anything>(yarn runs it in the member dir)cd packages/b && yarn add/upgrade …
The error is "./.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz": Tarball is not in network and can not be located in cache (["<root>/b/.socket/vendor/npm/…"]). This happens even when the member doesn't depend on the patched package. The same lock with the registry resolved installs fine from the member dir. Installs from the root still pass, which is all the existing workspace e2e covers. Once a root install has warmed the yarn cache, member-dir installs hit the cache slot and pass, so developers may not notice. Fresh CI checkouts that cd into a package fail.
Impact
Running yarn from a package directory is a normal yarn-1 workspaces workflow, and so is yarn workspace <name> add. After scan --mode vendored / vendor, both fail with a hard error in CI and on fresh clones. Nothing in docs/ecosystems.md or CLI_CONTRACT.md documents this limitation, and vendor prints no warning (it already warns yarn_classic_berry_migration_risk for a comparable install-time hazard).
Repro (yarn 1.22.22, Linux; same on 1.7.0 / 1.10.1)
mkdir -p w/a w/b && cd w
echo '{"name":"root","private":true,"workspaces":["a","b"]}' > package.json
echo '{"name":"a","version":"1.0.0","dependencies":{"left-pad":"^1.1.0"}}' > a/package.json
echo '{"name":"b","version":"1.0.0","dependencies":{"isarray":"2.0.5"}}' > b/package.json
yarn install
socket-patch vendor --json # (or scan --mode vendored) with a patch for pkg:npm/left-pad@1.3.0 → exit 0, applied 1
# lock: left-pad@^1.1.0: resolved "file:./.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz#…"
# fresh checkout (package.json files, yarn.lock, .socket/), cold cache:
export YARN_CACHE_FOLDER=$(mktemp -d)
yarn install --frozen-lockfile # from root: exit 0, left-pad patched ✔
cd b && yarn install --frozen-lockfile # exit 1: Tarball is not in network … (<root>/b/.socket/vendor/npm/…)
cd .. && yarn --cwd b install --frozen-lockfile # exit 1, same error
yarn workspace b add is-number@7.0.0 # exit 1, same errorControl 1: the pre-vendor lock (registry resolved) installs from b/ with exit 0. Control 2: a hand-written root dep "left-pad": "file:./vendor/left-pad-1.3.0.tgz" fails the same way from b/, so the underlying cause is yarn classic's cwd-relative file: handling. socket-patch is what introduces such an entry into a lock that installed fine before.
Expected vs actual
- Expected: CLI_CONTRACT / docs/ecosystems.md list yarn classic workspaces as supported for vendored mode ("Workspace-aware (walk members): npm / yarn / …"). A vendored lock should keep the project installable the ways it was before vendoring (the filing bar for vendored wiring is "the next frozen install must not fail"). Failing that, the limitation should be refused, warned about (as
vendor_pnpm_legacy_absolute_specifierdoes for pnpm 7/8 path-bound installs), or documented. - Actual:
vendor/scan --mode vendoredexit 0 with no warning, and every member-dir yarn command then fails on a cold cache.
OS × version
Linux = local sandbox (twice). macOS and Windows = probe run https://github.com/SocketDev/socket-patch/actions/runs/37123949202, which embeds socket-patch's exact vendored lock and tarball.
| OS | yarn | root frozen install | member-dir frozen install | --cwd b install |
yarn workspace b add |
baseline (registry lock) member install |
|---|---|---|---|---|---|---|
| Linux | 1.7.0 / 1.10.1 / 1.22.22 | pass (patched) | fail | fail | fail | pass |
| macOS | 1.7.0 / 1.10.1 / 1.22.22 | pass (patched) | fail | fail | fail | pass |
| Windows | 1.7.0 / 1.10.1 / 1.22.22 | pass (patched) | fail | fail | fail | pass |
Warm cache (a root install first, same YARN_CACHE_FOLDER): member-dir yarn add passes on all three Linux versions, which hides the problem locally.
Tested on main 045d7ec. Not bisected: the file:./ wiring has been the yarn classic vendored design since it landed.
Suspect code
crates/socket-patch-core/src/vendor/yarn_classic_lock.rs:143:let resolved_value = format!("file:./{rel_tgz}#{}", packed.sha1_hex);is a root-relative path that yarn classic reads cwd-relative. There's no workspace check or warning before the splice. Hosted mode is unaffected because it writes an absolute https URL.
Activity
yarn-classic: run 12 ledger (#691, #692)
mikolalysenko commentedon Oct 3, 2026
[agent] Triaged as
priority:p1(yarn classic). Not a duplicate; no open PR covers it. Cause is the root-relativefile:./resolvedvalue written atvendor/yarn_classic_lock.rs:143, which yarn classic resolves against the cwd.Generated by Claude Code
mikolalysenko commentedon Oct 7, 2026
[agent] Re-checked on main
1c6c509(yarn 1.22.22, Linux): still reproduces. After a vendored scan from the workspace root,yarn install --frozen-lockfilerun frompackages/afails withTarball is not in network and can not be located in cacheand looks forpackages/a/.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz. The #884 member-dir fix (#901) covers hosted scans only and doesn't change this.Generated by Claude Code
mikolalysenko commentedon Oct 8, 2026
[agent] Re-triage on main
cf8b164, yarn 1.22.22, Linux: still reproduces (×2). After a rootscan --mode vendored, runningyarn install --frozen-lockfilefrompackages/awith a cold cache fails witherror "./.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz": Tarball is not in network and can not be located in cache. yarn looks for the tarball underpackages/a/.socket/vendor/….Generated by Claude Code
mikolalysenko commentedon Oct 9, 2026
v5 release blocker (P1). Vendored Yarn classic must remain installable from ordinary workspace member directories.
This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.
mikolalysenko commentedon Oct 9, 2026
[agent] Claiming for v5 blocker burn-down (shared root cause: vendored yarn classic resolved file:./ path is cwd-relative in workspace members). Branch: agent/v5-yarn-classic-member-file. Claim-ID: 2026-10-09T16:42:08Z-8513a1
mikolalysenko commentedon Oct 9, 2026
[agent] Investigation for the v5 burn-down (PR #1324), yarn 1.22.22 on macOS, workspace
w/{a,b}, cold cache per run:resolvedspellinginstall --frozen-lockfilecd b && install --frozen-lockfilefile:./.socket/vendor/npm/u/left-pad-1.3.0.tgz#sha1(current)file:.socket/vendor/…./.socket/vendor/….socket/vendor/…Yarn 1's TarballFetcher tries
path.resolve(config.cwd, <resolved>), then the offline mirror (only whenyarn-offline-mirroris configured), then the cache slot. No relative spelling works from both the root and a member, and an absolute path breaks on any other checkout. An offline mirror would work, becauseyarn-offline-mirrorresolves against the.yarnrcdirectory. But yarn then copies every registry tarball the project installs into that mirror, so I ruled it out.Two forms do work from the member dir (verified, including
yarn workspace b add is-number@7.0.0):<member>/.socket/vendor/npm/<uuid>/<pkg>.tgzfor every workspace member (whether or not it uses the package), or<member>/.socketsymlink to../.socket. This breaks on Windows checkouts withcore.symlinks=false.Question for a maintainer: for v5, which one should vendored yarn classic do in a workspaces project?
(A) Keep the root-relative wiring, and warn and document the member-dir limitation. Installs from the root work and warm the cache.
(B) Also write a copy of each vendored tarball into every workspace member's
.socket/vendor/. That costs N× repo size and adds more files to commit and revert.(C) Refuse vendored mode for yarn classic workspaces and point to
--mode hosted.PR #1324 implements (A) as the interim: a
yarn_classic_workspace_member_install_riskrun-level warning plus docs. It does not close this issue.Warn on yarn classic member-dir vendored installs
Gate symlink lock test back under cfg(unix) for Windows (#691)
mikolalysenko commentedon Oct 13, 2026
[agent] Re-triage from the Yarn classic bug-hunt (ledger #304), main
15c2c83, Linux, yarn 1.22.22. #1324 behaves as designed:yarn_classic_workspace_member_install_risk.(cd a && yarn install --frozen-lockfile)still fails withTarball is not in network and can not be located in cache (["…/a/.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz", …]).I'm leaving this open for the
agent:needs-humandecision on whether the warning is the final fix.Generated by Claude Code