spawn ENOENT when using pathToClaudeCodeExecutable in Docker container

Resolved 💬 4 comments Opened Dec 18, 2025 by elijahbowie Closed Feb 25, 2026

TL;DR

The Claude Agent SDK (@anthropic-ai/claude-agent-sdk@0.1.72) fails to spawn the Claude Code CLI (@anthropic-ai/claude-code@2.0.72) inside a Cloudflare Container with spawn /usr/local/bin/claude ENOENT, despite the binary being installed and the pathToClaudeCodeExecutable option being explicitly set.

Environment

| Component | Value |
|-----------|-------|
| @anthropic-ai/claude-agent-sdk | 0.1.72 (installed in /opt/claude-agent-sdk/) |
| @anthropic-ai/claude-code | 2.0.72 (global install via npm install -g) |
| Base Image | docker.io/cloudflare/sandbox:0.6.6 |
| Node.js | v24 (from base image) |
| Runtime | Cloudflare Containers (Durable Objects) |

Error Details

Error Message:

Failed to spawn Claude Code process: spawn /usr/local/bin/claude ENOENT

Error Code: SPAWN_ERROR
Exit Code: 1
Retryable: false

Stack Trace:

Error: Failed to spawn Claude Code process: spawn /usr/local/bin/claude ENOENT
    at ChildProcess.<anonymous> (file:///opt/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs:13223:28)
    at ChildProcess.emit (node:events:524:28)
    at ChildProcess._handle.onexit (node:internal/child_process:293:12)

SDK Configuration Used

const options = {
  cwd,
  permissionMode: 'bypassPermissions',
  maxTurns: 100,
  // Explicit path to bypass PATH lookup
  pathToClaudeCodeExecutable: '/usr/local/bin/claude',
  executable: 'node',
  env: {
    PATH: '/usr/local/bin:/usr/bin:/bin',
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
    HOME: '/root',
    NODE_ENV: 'production',
  },
};

Expected Behavior

The SDK should spawn /usr/local/bin/claude successfully because:

  1. The Dockerfile runs npm install -g @anthropic-ai/claude-code@2.0.72 which creates /usr/local/bin/claude
  2. We explicitly pass pathToClaudeCodeExecutable: '/usr/local/bin/claude'
  3. We explicitly pass executable: 'node'
  4. We explicitly pass env.PATH including /usr/local/bin

Actual Behavior

The SDK throws ENOENT at sdk.mjs:13223 when attempting to spawn the process.

Dockerfile (Relevant Sections)

FROM docker.io/cloudflare/sandbox:0.6.6

# Global install creates /usr/local/bin/claude
RUN npm install -g npm@11.7.0 && \
    npm install -g @anthropic-ai/claude-code@2.0.72 && \
    npm cache clean --force

# Local SDK installation
ARG CLAUDE_SDK_VERSION=0.1.72
RUN mkdir -p /opt/claude-agent-sdk && \
    cd /opt/claude-agent-sdk && \
    npm init -y && \
    npm install "@anthropic-ai/claude-agent-sdk@${CLAUDE_SDK_VERSION}"

ENV PATH="/usr/local/bin:/usr/bin:/bin:/root/.local/bin:$PATH"

Observations

  1. Pre-flight validation passes: Our agent-runner calls accessSync('/usr/local/bin/claude', constants.X_OK) before invoking the SDK and it passes
  2. Error originates inside SDK: The ENOENT comes from sdk.mjs:13223, not from our code
  3. Timing correlation: Error occurred immediately after Durable Object resets due to code deployment

Hypotheses (Prioritized)

  1. SDK ignores pathToClaudeCodeExecutable in certain code paths - The SDK may have internal logic that still attempts PATH-based resolution despite the explicit path option
  2. SDK spawns a different binary than expected - Perhaps the SDK internally calls something other than the pathToClaudeCodeExecutable
  3. Child process environment not properly inherited - Despite passing env, the spawned process may not receive the correct environment in the Cloudflare Container runtime

Questions

  1. At sdk.mjs:13223, what exact command/path is being passed to child_process.spawn()? Is it using our pathToClaudeCodeExecutable value or something else?
  2. Does the SDK spawn the Claude Code CLI directly, or does it spawn an intermediate process?
  3. Are there any additional environment variables or options required for Docker/container environments?
  4. Is there a debug mode or verbose logging option in the SDK to capture the actual spawn arguments?
  5. Does SDK version 0.1.72 have any known issues with pathToClaudeCodeExecutable being ignored?

Reproduction Steps

  1. Build container with the Dockerfile above
  2. Deploy to Cloudflare Containers
  3. Send a request that triggers query() from @anthropic-ai/claude-agent-sdk
  4. Observe ENOENT error in logs

Related Issues

  • #4383 (similar PATH inheritance issue in Docker)

Log Excerpt

2025-12-18T13:16:12.310Z [AgentSdkExecutor] Starting agent-runner process
2025-12-18T13:16:12.310Z [init] {"cwd":"/workspace/projects/...","maxTurns":100}
2025-12-18T13:16:12.310Z [error] {"type":"error","message":"Failed to spawn Claude Code process: spawn /usr/local/bin/claude ENOENT","code":"SPAWN_ERROR","retryable":false}
2025-12-18T13:16:12.310Z [exit] exitCode=1

View original on GitHub ↗

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