Concurrent `claude` sessions racing on npm-global auto-update causes ENOTEMPTY + missing native binary
Summary
Running multiple concurrent claude CLI processes (same machine, npm-global install) can cause the background auto-updater to race when two processes attempt to update at the same time. This has recurred ~4 times over a few days.
Environment
- claude-code: 2.1.236 (npm-global install)
- node: v24.3.0 / npm: 11.4.2
- macOS 26.5, arm64 (Apple Silicon)
- Install path: /opt/homebrew/lib/node_modules/@anthropic-ai/claude-code
What happened
- Two
claudeprocesses were alive at once (e.g. one long-running session since the previous day, another started via a shell alias that swaps CLAUDE_CODE_OAUTH_TOKEN for a different account). ~/.claude/backups/.claude.json.backup.*timestamps show the auto-updater polling roughly every 30–40 minutes.- At some point the install ends up in a broken state:
bin/claude.exebecomes a tiny ~500 byte shim script (not the ~300MB native binary), invoking it prints:
````
Error: claude native binary not installed.
...
Run the postinstall manually: node node_modules/@anthropic-ai/claude-code/install.cjs
- Running that postinstall script reports the platform-native optional dependency (
@anthropic-ai/claude-code-darwin-arm64) was not found. - A subsequent
npm install -g @anthropic-ai/claude-code@latestfails with:
````
npm error code ENOTEMPTY
npm error syscall rename
npm error path .../@anthropic-ai/claude-code
npm error dest .../@anthropic-ai/.claude-code-<random>
npm error ENOTEMPTY: directory not empty, rename ...
- Root cause appears to be a leftover temp rename directory (
.claude-code-<random>) from a previous interrupted/racing update, which blocks the next rename. Deleting that stale directory and re-runningnpm install -gfixes it — until it recurs.
Reproduction (best guess)
- Start a long-running
claudesession. - Later, open a second terminal and start another
claudesession (optionally under a different account viaCLAUDE_CODE_OAUTH_TOKENenv override). - Wait for both processes' background auto-update checks to land around the same time.
- Occasionally, the npm-global rename step races between the two processes, leaving a stale
.claude-code-<random>temp dir and a half-installed package (missing native binary).
Impact
The CLI becomes unusable (claude native binary not installed) until manually repaired via npm install -g @anthropic-ai/claude-code@latest (after removing the stale temp directory). This has happened ~4 times over a few days for a user who routinely runs multiple concurrent sessions (e.g. switching between work/personal accounts via shell aliases).
Suggested fix directions
- Add cross-process locking (e.g. a lockfile) around the npm-global self-update rename step, or skip the update attempt if another instance is already mid-update.
- Detect and clean up stale
.{pkg}-<random>temp directories left over from an interrupted update before starting a new one. - Document
DISABLE_AUTOUPDATER=1more prominently as a workaround for multi-session setups.
Workaround
Setting DISABLE_AUTOUPDATER: "1" under env in ~/.claude/settings.json avoids the background auto-update entirely.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗