Claude Desktop: gh spawn ENOENT — hardcoded /opt/homebrew path fails in sandbox

Resolved 💬 2 comments Opened May 14, 2026 by Paul-Kyle Closed May 17, 2026

Bug report: Claude Desktop spawns gh from sandbox path that doesn't exist there

Summary

Claude Desktop's [GitHubPrManager] repeatedly tries to spawn /opt/homebrew/bin/gh and fails with ENOENT, polluting main.log with stack traces and (suspected) contributing to session instability in repos with many worktrees.

Environment

  • Claude Desktop (macOS), build current as of 2026-05-14
  • macOS Darwin 25.2.0
  • Host: gh v2.92.0 is correctly installed at /opt/homebrew/bin/gh (Homebrew symlink → ../Cellar/gh/2.92.0/bin/gh)
  • which gh from host shell: /opt/homebrew/bin/gh (resolves)

Observed behavior

In ~/Library/Logs/Claude/main.log, repeated entries like:

2026-05-14 13:59:08 [info] LocalSessions.getPrChecks: cwd=/Users/admin/Code/.../friendly-noyce-9103f0, prNumber=362
2026-05-14 13:59:08 [error] [GitHubPrManager] Failed to get PR checks:
  Failed to spawn /opt/homebrew/bin/gh: spawn /opt/homebrew/bin/gh ENOENT
    at ChildProcess.<anonymous> (/Applications/Claude.app/Contents/Resources/app.asar/.vite/build/index.js:162:109466)
    at ChildProcess.emit (node:events:521:24)
    ...

Cadence: triggered on a ~30s polling cycle per open session, multiplied by:

  • Number of worktrees in the repo (sweep cycle)
  • Number of branches per worktree

In one MM-KMD repo with 51 worktrees, this produced ~328 log entries within a single session window before cleanup.

Why this matters

  1. Log noise: hundreds of stack traces per minute drown real signal
  2. Wasted spawn syscalls at scale
  3. Suspected session instability: in repos with many worktrees + many branches, sessions appear to close unexpectedly well below context-window limits. Causal link not proven, but high-volume failing spawns + [SkillsPlugin] Skills request timed out events correlate with the close timing.

Likely root cause

Claude Desktop runs node from a sandboxed environment (per ~/Library/Logs/Claude/claude_vm_swift.log, processes are spawned by a VM with isolated PATH/filesystem view). /opt/homebrew/bin is not exposed inside that sandbox, so even though gh exists on the host, the sandboxed node process can't reach it.

Suggested fixes (any of)

  1. PATH-resolve gh at spawn time instead of hardcoding /opt/homebrew/bin/gh. Use which gh or command -v gh so the sandbox's actual PATH is consulted.
  2. Detect ENOENT once per repo, then skip PR checks for that session rather than retrying every 30s for each worktree/branch. Cache the failure.
  3. Expose /opt/homebrew/bin (and /usr/local/bin) inside the Claude Desktop sandbox so common CLI tools resolve.
  4. Provide a setting (e.g., gh.path or disablePrChecks: true) to let users either point at the right binary or turn off the feature.

Reproduction

  1. Have gh installed via Homebrew on macOS (Apple Silicon)
  2. Open a repo in Claude Desktop with several git worktrees (git worktree add ≥3)
  3. Watch tail -f ~/Library/Logs/Claude/main.log | grep gh — failing spawns appear on each polling cycle

Workaround (user-side)

  • Aggressively prune stale worktrees (git worktree remove + git worktree prune)
  • This reduces the volume of failing spawns but does not eliminate them

Filed by

Paul Kyle (paulkyle@gmail.com), 2026-05-14
Captured from MM_KMD repo (Kill My Darlings narrative project), confirmed in palinode-dev as well.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗