headroomlabs-ai/headroom · error · SystemExit
Error: 'claude' not found in PATH.
Error message
Error: 'claude' not found in PATH.
What it means
Before wrapping Claude Code, Headroom resolves the `claude` binary with shutil.which('claude'). If it is not on PATH, it prints this error plus the official install URL and raises SystemExit(1) — no proxy is started, nothing is modified. The check is skipped entirely when --prepare-only is passed.
Source
Thrown at headroom/cli/wrap.py:4756
\b
Examples:
headroom wrap claude # Start everything (Serena code memory)
headroom wrap claude --memory # With persistent memory
headroom wrap claude --resume <id> # Resume a session
headroom wrap claude -- -p # Claude in print mode
headroom wrap claude --no-mcp # Skip MCP retrieve tool registration
headroom wrap claude --code-memory none # No code-memory MCP
headroom wrap claude --1m # Preserve the 1M context window
"""
if prepare_only:
return
claude_bin = shutil.which("claude")
if not claude_bin:
click.echo("Error: 'claude' not found in PATH.")
click.echo("Install Claude Code: https://docs.anthropic.com/en/docs/claude-code")
raise SystemExit(1)
# Validate --tool-search up front so a typo fails before we start the proxy.
if tool_search is not None:
tool_search = _normalize_tool_search_mode(tool_search)
proxy_holder: list[subprocess.Popen | None] = [None]
_saved_base_url: list[str | None] = [None] # previous settings.json value for restore
_tool_search_not_written = object()
_saved_tool_search: list[object | str | None] = [_tool_search_not_written]
_settings_foundry: list[bool] = [False]
port_holder: list[int] = [port]
_settings_vertex: list[bool] = [False]
# Bind before the try so the finally can always reference it. It is otherwise
# only assigned inside the try (after _ensure_proxy, which can raise), so an
# early proxy-start failure would make the finally raise UnboundLocalError,
# masking the real error and skipping cleanup(). Mirrors the holders above.
_wrap_settings_path = Path.cwd() / ".claude" / "settings.local.json"
_raise_on_claude_auth_conflict(View on GitHub (pinned to 322425c43b)
Solutions
- Install Claude Code: npm install -g @anthropic-ai/claude-code (or the official installer at docs.anthropic.com)
- Verify resolution in the same shell: `which claude` — if empty, fix PATH to include the npm global bin dir
- For nvm users, run `nvm use <version>` in the shell before `headroom wrap claude`
- If you only want proxy/config preparation without launching, use `headroom wrap claude --prepare-only`
Example fix
# before headroom wrap claude # Error: 'claude' not found in PATH. # after npm install -g @anthropic-ai/claude-code which claude && headroom wrap claude
Defensive patterns
Strategy: type-guard
Validate before calling
import shutil
if not shutil.which("claude"):
raise SystemExit("Install Claude Code first: npm install -g @anthropic-ai/claude-code") Type guard
import shutil
def claude_available() -> bool:
"""True when the Claude Code CLI is resolvable on PATH."""
return shutil.which("claude") is not None Prevention
- Run `which claude` in the same shell that launches headroom
- For nvm users, load the node version owning the global install first
- Automate the check in setup scripts before calling headroom wrap claude
When it happens
Trigger: Running `headroom wrap claude` (without --prepare-only) on a machine where `claude` is not installed or not on PATH: Claude Code never installed, installed via a node version manager whose bin dir isn't in this shell's PATH, or installed only for a different user.
Common situations: Fresh machines; nvm/fnm users opening a shell without loading the node version that owns the global npm bin; installing Claude Code with a different package manager (native installer) that puts `claude` in a non-PATH location; CI images that install headroom but not claude.
Related errors
- Error: 'copilot' not found in PATH.
- Error: 'codex' not found in PATH.
- Error: 'aider' not found in PATH.
- Error: 'openclaude' not found in PATH.
- Error: 'vibe' not found in PATH.
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/f4cfd3a88e639351.
Report an issue: GitHub.