Graphify-Labs/graphify · error · RuntimeError
Claude Code CLI not found on $PATH. Install from https://cla
Error message
Claude Code CLI not found on $PATH. Install from https://claude.ai/code and run `claude` once to authenticate.
What it means
Raised on non-Windows platforms (and on Windows when neither `claude.cmd` nor plain `claude` resolves) when `shutil.which("claude")` returns None — the Claude Code CLI executable is not on $PATH. The `claude-cli` backend shells out to this binary, so it must be installed and locatable before extraction can run. On Windows the code first prefers `claude.cmd` over `claude.ps1` because CreateProcess cannot execute .ps1 files (issue #1072).
Source
Thrown at graphify/llm.py:1492
is allowlisted with `--add-dir` so the read is permitted.
"""
import platform
import shutil
import subprocess
# On Windows, npm installs `claude` as both `claude.ps1` and `claude.cmd`
# alongside each other. When PATHEXT lists `.PS1` before `.CMD`,
# `shutil.which("claude")` returns `claude.ps1`, which `CreateProcess`
# cannot execute directly — it raises `[WinError 2] The system cannot
# find the file specified`. `claude.cmd` IS executable by CreateProcess,
# so prefer it explicitly on Windows. See issue #1072.
claude_cmd = "claude"
if platform.system() == "Windows":
cmd_path = shutil.which("claude.cmd")
if cmd_path:
claude_cmd = cmd_path
elif shutil.which("claude") is None:
raise RuntimeError(
"Claude Code CLI not found on $PATH. Install from "
"https://claude.ai/code and run `claude` once to authenticate."
)
elif shutil.which("claude") is None:
raise RuntimeError(
"Claude Code CLI not found on $PATH. Install from "
"https://claude.ai/code and run `claude` once to authenticate."
)
# Deliver the extraction instructions in the USER turn rather than via
# --system-prompt. Newer Claude Code CLIs (>= ~2.1) do not treat a
# --system-prompt as the sole authority: they still layer in the local
# coding-agent context (CLAUDE.md/AGENTS.md in cwd, skills, MCP) and, when
# the user turn is only a raw file dump with no request, reply
# conversationally ("I see the file, but there's no actual request
# attached — what would you like me to do with it?"). That prose parses to
# zero nodes/edges, so _response_is_hollow flags it as truncation and the
# adaptive-retry path bisects the chunk indefinitely, never converging andView on GitHub (pinned to 7fe58b0b0f)
Solutions
- Install Claude Code CLI from https://claude.ai/code and run `claude` once interactively to authenticate.
- Ensure the install location is on $PATH for the exact process invoking graphify: `which claude` (or `where claude` on Windows) must succeed; for npm installs add the npm global bin dir.
- In containers/services, set PATH explicitly or symlink the binary into a standard directory like /usr/local/bin.
- On Windows, if only claude.ps1 exists, reinstall via npm so claude.cmd is generated, since .ps1 cannot be spawned by CreateProcess.
Example fix
# before (claude installed but not on service PATH) ENV PATH=/app/bin # after ENV PATH=/app/bin:/usr/local/bin # npm i -g @anthropic-ai/claude-code installs into /usr/local/bin
Defensive patterns
Strategy: validation
Validate before calling
import shutil
if shutil.which("claude") is None:
raise SystemExit("Claude Code CLI missing — install from https://claude.ai/code and re-run") Prevention
- Add a `shutil.which("claude")` preflight in scripts that use backend="claude-cli".
- In Dockerfiles, install the CLI and keep npm's global bin on PATH.
- In services/cron, set PATH explicitly to include the CLI's install directory.
When it happens
Trigger: Calling `extract_files_direct(..., backend="claude-cli")` on Linux/macOS where `shutil.which("claude")` is None; or on Windows where both `claude.cmd` and `claude` are absent.
Common situations: Claude Code CLI never installed; installed via npm but npm's global bin directory is not on $PATH for the shell/process running graphify; running graphify from a service/container/cron environment with a minimal PATH; Windows npm stub issue (#1072).
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- claude -p produced unparseable JSON envelope: {exc}; first 5
- claude -p returned a JSON array with no result object; first
- claude -p exited {proc.returncode}: {detail[:500]}
- Claude Code CLI not found on $PATH
- graph not found: {source_path}
AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14).
Data as JSON: /api/errors/c289d75b9fd2a91f.
Report an issue: GitHub.