Skip to content

fix: show actionable message when Claude Code native binary is missing - #874

Draft
claude[bot] wants to merge 1 commit into
mainfrom
fix/friendly-claude-binary-error
Draft

fix: show actionable message when Claude Code native binary is missing#874
claude[bot] wants to merge 1 commit into
mainfrom
fix/friendly-claude-binary-error

Conversation

@claude

@claude claude Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Requested by Kaia Peacock · Slack thread

Summary

Two related changes around the Claude Agent SDK's per-platform native claude binary.

1. Turn the raw "native binary not found" SDK error into an actionable message (primary deliverable).

The SDK (@anthropic-ai/claude-agent-sdk) resolves its per-platform native binary at query() time via @anthropic-ai/claude-agent-sdk-<platform> optional dependencies. When that binary isn't present it throws, and the wizard used to relay the raw SDK stack verbatim.

  • Before: the user hit a raw SDK stack — ReferenceError: Claude Code native binary not found at /app/node_modules/.pnpm/@anthropic-ai+claude-agent-sdk-linux-x64-musl@<ver>/.../claude. Please ensure Claude Code is installed via native installer or specify a valid path with options.pathToClaudeCodeExecutable. — with no explanation of the likely cause or fix.

  • After: a clear, concise message naming the current platform and the most likely cause (cross-OS/libc node_modules copy) plus the three fixes:

    Claude Code's native binary for your platform (<os>-<arch>[-<libc>]) wasn't found.
    
    This usually means the platform-specific @anthropic-ai/claude-agent-sdk optional
    dependency didn't get installed — most often because node_modules was installed on
    a different OS or libc (e.g. glibc) and copied into this environment (e.g.
    Alpine/musl), so only the wrong-platform binary was materialized.
    
    To fix:
      • Reinstall dependencies in this environment instead of copying node_modules
        across OS/libc boundaries.
      • If you use pnpm, set pnpm.supportedArchitectures (os / cpu / libc, e.g.
        libc: [glibc, musl]) to include this platform, then reinstall.
      • Or point the SDK at an existing Claude Code binary via
        options.pathToClaudeCodeExecutable.
    

2. Remove the stale cli.js binary-path references exposed by the SDK 0.3.x bump (#872).

getClaudeCodeExecutablePath() returned <sdkDir>/cli.js, which @anthropic-ai/claude-agent-sdk 0.3.219 no longer ships (only sdk.mjs + native binary). In agent-interface.ts it was log-only. In mcp-with-fallback.ts it was passed to query() as claudeCodePath — but that is not a real SDK option name (the SDK reads pathToClaudeCodeExecutable), so the override was already being silently ignored. Removing both lets the SDK do its own platform-aware resolution (the primary agent-interface.ts path never passed a path and works this way). This is a separate, real bug the 0.3.x bump exposed in the MCP-fallback path; fixing it prevents that path from handing the SDK a dead path.

How

  • New module src/lib/agent/native-binary-error.ts: isNativeBinaryMissingError() (robust matcher for both SDK message shapes — native binary not found / Native CLI binary for … / pathToClaudeCodeExecutable + not found), describeCurrentPlatform() (<os>-<arch> + best-effort libc via the Node process report), and formatNativeBinaryMissingMessage().
  • Chokepoint: runAgent's outer catch in src/lib/agent-interface.ts. The error is deterministic and matches no transient-retry pattern, so it re-throws to the outer catch on the first attempt (no retry loop). There it's classified as the new AgentErrorType.NATIVE_BINARY_MISSING and returned with the remediation message; the raw error is preserved in the log file.
  • src/lib/agent-runner.ts adds a branch that routes NATIVE_BINARY_MISSING through the existing wizardAbort + emitRunError path (tagged recoverable: 'human_required', exit code AGENT_FAILED), so both interactive (TUI Outro) and --agent/--ci (NDJSON) modes show the friendly message. NATIVE_BINARY_MISSING added to the emitRunError code union in wizard-ui.ts and agent-ui.ts.
  • Removed the stale getClaudeCodeExecutablePath() from agent-interface.ts (log-only) and mcp-with-fallback.ts (ignored claudeCodePath override + now-unused path import).

Test plan

  • New unit test src/lib/agent/__tests__/native-binary-error.test.ts (7 tests): asserts the friendly message is produced for the representative production WIZARD-CLI-19 error (both message shapes), a bare-string message, non-matching errors, and that all three remediation paths + the platform label appear.
  • pnpm build ✅ · pnpm lint ✅ · pnpm test — only the 35 known-preexisting src/utils/__tests__/direct-signup.test.ts failures (sandbox URL quirk) remain; all other 308 test files (4610 tests) pass, including the new test.

Notes

  • Addresses Sentry WIZARD-CLI-19. The production error path references the platform .../claude binary (the cross-libc install issue), which is a userland install-config problem — this change does not alter platform support; it just makes the failure self-explanatory.
  • This is a Claude-authored change. CLAUDE.md's PR conventions mention a /reflect checklist; noted here rather than run.

Checklist

  • Opened PR after push
  • pnpm lint and pnpm test pass (only the 35 known-preexisting direct-signup sandbox failures remain)
  • TUI / router / flows.ts / navigation store.ts changes — N/A (no TUI screen/router/store/flow changes)
  • /reflect — noted above as a Claude-authored change
  • LLM call-site changes — N/A (no call-site added/removed/changed)

Generated by Claude Code

The Claude Agent SDK resolves its per-platform native `claude` binary at
query() time via `@anthropic-ai/claude-agent-sdk-<platform>` optional
dependencies. When that binary isn't present (Sentry WIZARD-CLI-19) — almost
always because node_modules was installed on one OS/libc and copied into a
different runtime — the SDK threw a raw stack that the wizard relayed
verbatim.

Detect that failure at the SDK-invocation chokepoint (runAgent's outer catch)
and classify it as a new AgentErrorType.NATIVE_BINARY_MISSING, then surface a
concise remediation message (reinstall in-place / set
pnpm.supportedArchitectures / pass options.pathToClaudeCodeExecutable) through
the existing agent-runner error path so both interactive (TUI Outro) and
--agent/--ci (NDJSON) modes benefit. The original error is preserved in the
log file.

Also removes the stale `getClaudeCodeExecutablePath()` cli.js references
exposed by the SDK 0.3.x bump: it was log-only in agent-interface.ts, and in
mcp-with-fallback.ts it was passed as `claudeCodePath` (a non-existent SDK
option name pointing at a file 0.3.x no longer ships), so it was already being
ignored — removing it lets the SDK do its own platform-aware resolution.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VMfU7ooAmKSV4U5tXYhXFQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant