Skip to content

pnpm node-linker=pnp with a modulesDir is refused as yarn Plug'n'Play, because the layout detector ignores the modulesDir the crawler honors #1129

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: register comment.

Kind: bug (one pnpm layout question answered two ways, proven by execution against a real pnpm install). Source: new finding; register E92 (related to E40 and E48).

Problem

"Where does pnpm keep this project's install?" has two answers:

pnpm's node-linker=pnp writes a .pnp.cjs. When modulesDir is also set, the store is <modulesDir>/.pnpm, so the carve-out fails and the tree is classified YarnBerryPnP. Three consumers act on that classification:

  • agent apply refuses with yarn_pnp_unsupported and "Use yarn patch <pkg>" (apply.rs#L1332-L1341, and apply --check at #L604-L612);
  • the vendored router skips its vendor_pnpm_pnp_unsupported diagnosis and refuses with vendor_yarn_berry_unsupported and the yarn remedy instead (npm_flavor.rs#L181-L210);``
  • VEX reads pnpm's .pnp.cjs as a yarn loader (YarnPnpLoader::detect).``

Meanwhile the crawler finds every copy under deps/.pnpm, and agent mode could patch them.

Proof, run twice on e2d9633 with a real pnpm 10.28.0 install: package.json depends on left-pad@1.3.0, .npmrc = node-linker=pnp + modules-dir=deps, then pnpm install. The install wrote .pnp.cjs, deps/.modules.yaml, deps/.pnpm/ and deps/left-pad; node_modules/ holds only .pnpm-workspace-state-v1.json.

Probe (throwaway tests) modules-dir=deps control: same project without modules-dir
pnpm_modules_dirs (crawler roots) [<root>/deps, <root>/deps] n/a
detect_npm_pkg_manager YarnBerryPnP Pnpm
pnpm_pnp_layout false true
YarnPnpLoader::detect(..).is_some() true false
socket-patch apply --json --offline with a one-patch npm manifest exit 1, yarn_pnp_unsupported, "packages live inside .yarn/cache zips… Use yarn patch <pkg>" n/a

Smaller detail: the crawler lists the deps root twice.

Symptoms

None filed. #698 fixed the crawler half (#661, #696), and #859 is the same pattern for yarn's pnpmStoreFolder. This is one more place where the package-manager layout is spelled outside the crawler (E40/#855, E48).

Impact: a pnpm project using its Plug'n'Play linker with a custom modulesDir can't use agent mode, gets the wrong refusal and remedy in vendored mode, and has VEX consult the wrong loader. This combination is uncommon. Plain pnpm with modulesDir only loses the pnpm notice, because detect falls through to Npm/Unknown.

Proposed change

  1. Move the modules-dir resolution (pnpm_modules_dir_setting, resolve_modules_folder and the YAML unquote) out of npm_crawler.rs into one pnpm layout helper, for example crawlers/pnpm_layout.rs or formats::pnpm::workspace. Have it answer "the project's pnpm modules dirs" for both a disk root and a ProjectView.
  2. detect_npm_pkg_manager step 4 and pnpm_pnp_layout_in look for .modules.yaml / .pnpm under those dirs instead of the literal node_modules.
  3. The crawler's pnpm_modules_dirs calls the same helper and deduplicates its roots.
  4. Delete the hard-coded node_modules/.modules.yaml / node_modules/.pnpm probes in pkg_managers.rs.

Size and scope

Acceptance criteria

Dependencies


Backlog review — 2026-10-08

Priority: unassigned → P2. Keep the reproduced pnpm PnP/custom-modulesDir layout defect. It blocks agent apply and gives the wrong package-manager diagnosis in a specific supported layout. The report does not demonstrate a successful false attestation; P2 fits the conditional compatibility failure.

Activity

  1. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Claiming this issue for the architecture refactor routine (highest leverage: the top free candidate, one pnpm modules-dir helper replacing the crawler's private resolver and the hard-coded node_modules probes in pkg_managers.rs). Branch: arch-refactor/1129-pnpm-modules-dir. Claim-ID: 2026-10-09T16:55:52Z-7c3a91


    Generated by Claude Code

  2. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] PR: #1347. It adds one helper, crawlers::pnpm_layout, used by the crawler, detect_npm_pkg_manager, the PnP carve-out (disk, snapshot and memory views), YarnPnpLoader::detect and the vendored router. The node_modules-only probes are deleted. All acceptance criteria are covered, including the CLI apply --json test, which shows red on main and green on the branch.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:claimedagent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)bugSomething isn't workingpm:pnpmpnpmpriority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions