Stale background daemons from prior version cause ENOENT posix_spawn when launching agents after upgrade
Status Fixed / completed
Reported on v2.1.128
Maintainer reply ✓ Yes — bogini
Workaround ✓ Mentioned in thread ↓
Activity 4 comments · opened May 19, 2026 · closed May 27, 2026
💡 Likely answer: A maintainer (bogini, collaborator)
responded on this thread — see the highlighted reply below.
What happened
After Homebrew upgraded the claude-code cask from 2.1.128 → 2.1.138, launching any new agent fails with:
ENOENT: no such file or directory, posix_spawn '/opt/homebrew/Caskroom/claude-code/2.1.128/claude'; respawning
Restarting the foreground claude process does NOT fix it.
Root cause
Long-lived background processes from the previous version survive the cask upgrade. The 2.1.128 Caskroom directory has been deleted by Homebrew, but these daemons remain running with the old absolute path in their argv[0]:
PID ... /opt/homebrew/Caskroom/claude-code/2.1.128/claude daemon run --origin transient --spawned-by {...}
PID ... /opt/homebrew/Caskroom/claude-code/2.1.128/claude --bg-pty-host /tmp/cc-daemon-.../spare/....pty.sock 200 50 -- ...
PID ... /opt/homebrew/Caskroom/claude-code/2.1.128/claude --bg-spare /tmp/cc-daemon-.../spare/....claim.sock
When a new agent is spawned, the daemon re-execs its own argv[0] (the deleted 2.1.128 path), so posix_spawn returns ENOENT and the "respawning" loop never recovers.
Workaround
pkill -f 'Caskroom/claude-code/2\.1\.128'
# then start a fresh `claude` session — daemon respawns from 2.1.138
Suggested fixes
- On daemon startup, resolve the binary via
/opt/homebrew/bin/claude(or another stable path), not the versioned Caskroom path. - Detect a missing argv[0] on respawn and exit cleanly so a new daemon can be started from the current binary, instead of looping.
- Have the foreground process check the daemon's binary path on connect and kill+respawn the daemon if it points to a deleted version.
Environment
- macOS (darwin 25.4.0)
- Installed via Homebrew Cask
- Affected versions observed: 2.1.128 daemons left over after upgrade to 2.1.138
4 Comments
🔧 Proposed Solution: 3-Layer Daemon Self-Healing
Root Cause
After Homebrew upgrades the claude-code cask, long-lived background daemons from the previous version survive with the old versioned path in
argv[0]. When the new foreground process spawns daemons, the internal respawn logic re-execs the deleted path → ENOENT → infinite respawn loop.Fix (3 independent layers — any single layer resolves the issue)
Layer 1: Daemon self-healing on ENOENT — Detect missing binary path, resolve via stable symlink (
/opt/homebrew/bin/claude), or exit cleanly (code 78) to allow foreground process to restart from current binary.Layer 2: Foreground process daemon validation — On startup, check running daemon's binary path via proc cmdline. If binary is deleted, kill stale daemon before it causes problems.
Layer 3: Stable binary resolution — New daemons resolve binary via stable path (Homebrew symlink or PATH lookup), not versioned Caskroom path. Survives cask upgrades.
Why This Works
Competitive Edge
has reprolabel — maintainer-tracked---
Full solution details in attached analysis.
---
<details>
<summary>📋 Full Technical Analysis</summary>
Solution: claude-code #60634 — Stale Background Daemons ENOENT After Upgrade
Issue Summary
After Homebrew upgrades claude-code cask (e.g., 2.1.128 → 2.1.138), long-lived background daemons from the previous version survive with the old absolute path in argv[0]. When the new foreground process tries to respawn daemons, it re-execs the deleted versioned path, causing ENOENT posix_spawn loop.
Root Cause Analysis
The Problem Chain
/opt/homebrew/Caskroom/claude-code/2.1.128/with2.1.138//opt/homebrew/Caskroom/claude-code/2.1.128/claudeWhy Restarting Foreground Process Doesn't Fix It
The foreground process does NOT kill existing daemons on startup. It checks for a running daemon via the socket/claim file and reuses it. The stale daemon continues to use the deleted path for any internal respawn operations.
Proposed Fix (3-layer approach)
Layer 1: Daemon Self-Healing on ENOENT
Layer 2: Foreground Process Daemon Validation
Layer 3: Stable Binary Resolution
Why This Fix Works
Estimated Impact
Competitive Analysis
has repro,area:packaging,area:agent-view— maintainer-tracked</details>
Recurred on 2.1.138 → 2.1.139 Homebrew cask upgrade today (2026-05-20).
Same failure mode: foreground
claudeis on the new 2.1.139 binary, but the long-lived daemon and its bg-pty-host / bg-spare children are still pointing at the now-deleted 2.1.138 Caskroom path.Process snapshot before cleanup:
Installed cask at the time: 2.1.139 (only directory remaining under
/opt/homebrew/Caskroom/claude-code/). Manual \kill\of the daemon tree was again required to recover.Confirms this is reproducible across at least two consecutive cask upgrades and not specific to the 2.1.128 → 2.1.138 jump.
Addressed by a merged fix. Please reopen with a fresh repro if you still see this on a current version.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.