[BUG] Sandbox: pnpm hangs forever when the project pins another pnpm version, and the write denial is never reported

Status Open
Reported on v2.1.278
Maintainer reply None cached
Activity 0 comments · opened Oct 2, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

On macOS, with the Bash sandbox on, every pnpm command hangs forever (even pnpm --version) in a project whose package.json pins a pnpm version that differs from the installed one. That happens through packageManager or through devEngines.packageManager with onFail: "download".

The cause is a filesystem write denial:

  1. To switch versions, pnpm 12 takes a directory lock at ~/Library/pnpm/package-manager-store/v11/tmp/engine-locks/pnpm@<version>.lock (mkdir style lock).
  2. ~/Library/pnpm is not in the sandbox write allowlist, so mkdir fails with EPERM.
  3. pnpm does not fail on EPERM. It waits for the lock forever. This happens even when the wanted version is already in pnpm's local cache.

Two problems make this hard to work with in Claude Code:

  • The denial is silent. A blocked network host shows up in a <sandbox_violations> block. A blocked filesystem write shows nothing. The command just hangs until the Bash timeout, so neither the agent nor the user can tell that the sandbox caused it. It took manual work to find the cause: comparing versions, reading strings from the pnpm binary, and testing mkdir directly.
  • There is no sandboxed way out. pnpm install needs write access to the pnpm home (~/Library/pnpm on macOS) in any case. The only fallback is dangerouslyDisableSandbox, and auto mode correctly denies that. So the agent cannot run pnpm at all in such a project.

The endless wait on EPERM is pnpm's behavior and belongs in a separate pnpm report. This issue is about the Claude Code side: the denial is not reported, and the default write allowlist leaves out the package manager home.

What Should Happen?

  • Filesystem write denials should be reported to the agent the same way network denials are (path and operation), at least when a command times out after one.
  • Ideally, the sandbox should offer a documented way to allow common package manager homes and stores (~/Library/pnpm, ~/.local/share/pnpm, ~/.npm, ~/Library/Caches/pnpm), or the docs should name them as paths users usually need to add.

Error Messages/Logs

Steps to Reproduce

  1. Install pnpm 12.x (here: 12.5.1, the standalone native binary in ~/Library/pnpm).
  2. In a temp directory, create package.json:

``json
{ "name": "repro", "devEngines": { "packageManager": { "name": "pnpm", "version": "12.8.0", "onFail": "download" } } }
``

  1. In a Claude Code session with the Bash sandbox on, have Claude run pnpm --version in that directory.

Result: the command hangs until the Bash timeout. No <sandbox_violations> output appears.

Checks done inside the sandbox:

| Case | Result |
|---|---|
| Pinned version equals the installed one (12.5.1) | Prints 12.5.1 at once |
| Pinned 12.8.0, onFail: "error" | Fails at once with ERR_PNPM_BAD_PM_VERSION |
| Pinned 12.7.0, 12.8.0 or 12.8.1 (all already in pnpm's cache), onFail: "download" | Hangs |
| Same, with allowed_domains: ["registry.npmjs.org"] | Hangs (network is not the cause) |
| pnpm without a version switch, network access | Works |
| python3 -c "os.mkdir('~/Library/pnpm/package-manager-store/v11/tmp/engine-locks/pnpm@12.7.0.lock')" | EPERM |
| PNPM_CONFIG_MANAGE_PACKAGE_MANAGER_VERSIONS=false pnpm --version | Works (runs 12.5.1, skips the switch) |

Workaround: add ~/Library/pnpm to sandbox.filesystem write paths, or set PNPM_CONFIG_MANAGE_PACKAGE_MANAGER_VERSIONS=false (pnpm then runs the installed version instead of the pinned one).

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.278 (desktop app, Code tab), auto mode, Bash sandbox on (default config)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗