Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Vendored yarn berry PnP refusal keys only on .pnp.cjs: a lock-only PnP checkout vendors successfully, then every re-run in an installed checkout fails exit 1 with vendor_yarn_berry_unsupported

已關閉
#539 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@mikolalysenko 已經在處理了。

開始於 2026年10月7日。

  • #978 來自 @mikolalysenko —— 未關閉

評估

難度
4/5
預估耗時
3-5 天
新手友好度
68/100
Issue 類型
缺陷
描述清晰度
基本清楚
活躍度
活躍
技術堆疊
rust
領域
cli, tooling

研究方向

Start with the PnP marker checks in crates/socket-patch-core/src/vendor/npm_flavor.rs:137-166 and crates/socket-patch-core/src/vendor/lock_inventory/view.rs:379. Read the Yarn Berry cases in crates/socket-patch-cli/tests/e2e_vendor_yarn_berry_build.rs and reproduce the lock-only and installed-checkout runs. Done means PnP handling is consistent across both states and the documented behavior matches the resulting scan status.

由索引模型根據 Issue 內容生成。

描述

agent:triaged bug bughunt pm:yarn-berry priority:p1

[agent] Found by the scheduled Yarn Berry (2+) bug-hunt routine (ledger #305).

Summary

Vendored mode's yarn berry Plug'n'Play gate only checks whether a PnP loader file (.pnp.cjs / .pnp.js / .pnp.loader.mjs) exists. It never reads nodeLinker from .yarnrc.yml, and it never uses yarn 4's default linker, which is pnp. That leads to two inconsistent outcomes on the same PnP project:

  1. A lock-only checkout (CI, a fresh clone, .pnp.cjs gitignored) has no loader file yet. scan --mode vendored wires the root resolutions and the lock's file: entry, then exits 0 success. This happens even when .yarnrc.yml says nodeLinker: pnp explicitly. The wiring works: yarn install --immutable --check-cache passes, and the PnP runtime loads the patched bytes.
  2. After that yarn install, .pnp.cjs exists, so every later scan --mode vendored run fails with exit 1, partial_failure and vendor_yarn_berry_unsupported, for the package that is already vendored and already loading patched bytes. The refusal message says "there is nothing vendor could stage or rewire". In v5 that isn't true, because vendored mode downloads its tarball from the patch service and stages nothing from node_modules.

So the documented refusal ("yarn berry (node-modules linker; PnP refused)" in docs/ecosystems.md:17, and "Plug'n'Play … so vendor refuses it (vendor_yarn_berry_unsupported)" in docs/testing/yarn-berry-compatibility.md:9) misfires both ways. It doesn't fire on a PnP project without a loader file, and once the loader exists it breaks re-runs on a project vendored earlier.

Impact

  • A team that vendors from CI (lock-only) gets a green run, and the next scan --mode vendored in any installed checkout (a dev machine, or a CI job that runs yarn install first) exits 1. A patch upgrade (new uuid) through vendored mode is then impossible without deleting .pnp.cjs by hand.
  • Whether a project counts as "supported" depends on whether an untracked, generated file happens to exist, not on the project's configuration.
  • vendor --revert, vendor --check and vex still work in the installed PnP checkout (verified). Only the forward and re-run path is affected.

Repro (Linux, yarn 4.12.0 from @yarnpkg/cli-dist, local patch-API mock)

mkdir seed && cd seed
echo '{"name":"t1","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
printf 'nodeLinker: pnp\n' > .yarnrc.yml
yarn install                          # writes .pnp.cjs → PnP project
mkdir ../ci && cp package.json yarn.lock .yarnrc.yml ../ci/ && cd ../ci   # lock-only checkout
socket-patch scan --mode vendored --json --yes --api-url <mock> --org org --api-token x
#   exit=0 status=success; package.json gains resolutions.left-pad = file:./.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz
yarn install --immutable --check-cache  # exit 0
node -r ./.pnp.cjs -e "console.log(require('fs').readFileSync(require.resolve('left-pad'),'utf8').split('\n')[0])"
#   /* SOCKET-PATCHED */            ← PnP loads the vendored bytes
socket-patch scan --mode vendored --json --yes --api-url <mock> --org org --api-token x
#   exit=1 status=partial_failure
#   errorCode vendor_yarn_berry_unsupported: "found `.pnp.cjs`: this is a yarn berry Plug'n'Play project —
#   packages live inside .yarn/cache/ zips, not node_modules/, so there is nothing vendor could stage or rewire"

The mock serves /v0/orgs/org/patches/batch, by-package, view and patches/package, with a granted tarball artifact carrying the real sha512 of a patched left-pad-1.3.0.tgz. It is the same shape as the mocks in crates/socket-patch-cli/tests/e2e_vendor_yarn_berry_build.rs.

Expected vs actual

  • Expected: one consistent answer for a PnP project, derived from its configuration (nodeLinker in .yarnrc.yml, defaulting to pnp on berry), not from whether .pnp.cjs has been generated yet. Either refuse up front, including on a lock-only checkout (what the docs promise), or, since the file: wiring demonstrably works under PnP, accept PnP in both states and let re-runs stay idempotent for already-vendored packages.
  • Actual: accepted when .pnp.cjs is absent, refused once it exists, and the refusal's stated reason ("nothing vendor could stage") no longer holds in v5.

Matrix (Linux; 2/2 runs each)

yarn .yarnrc.yml lock-only vendored fresh --immutable --check-cache, PnP loads patched re-run after install
4.0.2 (default linker = pnp) exit 0 success yes exit 1 vendor_yarn_berry_unsupported
4.12.0 nodeLinker: pnp exit 0 success yes exit 1 vendor_yarn_berry_unsupported
4.18.1 (default linker = pnp) exit 0 success yes exit 1 vendor_yarn_berry_unsupported

macOS and Windows are untested. Probe branches are blocked this run, but the gate is a pure file-existence check, so I expect the same result there.

Tested on main 61cfb9b (CLI 4.0.0). I didn't bisect.

Suspect code

  • crates/socket-patch-core/src/vendor/npm_flavor.rs:166: the PnP gate is for marker in PNP_MARKERS { if exists(marker) … }, and step 5 (:137) assumes "YarnBerry (node-modules linker; PnP was already refused in step 1)", so any berry lock without a loader file counts as node-modules.
  • crates/socket-patch-core/src/vendor/lock_inventory/view.rs:379: same marker-only check, same message.

Related, but not a duplicate: #519 (PnP + hosted pin, stale-install vex attestation).

主要語言
Rust
星號
8
分支
0
平均合併
19 小時 44 分鐘
30 天內合併 PR
450

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

SocketDev/socket-patch 的其他 Issue

查看 SocketDev/socket-patch 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。