Skip to content

fix(agent): claude-code postinstall blocked by npm → agent image ships a stub 'claude', every task dies at turn 0 #609

Description

@ayushtr-aws

Component

Agent runtime (Dockerfile / container build)

Describe the bug

A freshly built agent image ships a 500-byte error stub in place of the native claude binary, so every task fails at turn 0 with:

ERROR step 'implement' handler raised: OSError: [Errno 8] Exec format error: 'claude'

The task record shows status=FAILED, turns=0, duration≈1s, and the terminal comment reads ❌ Task failed: Unexpected error.

Root cause

agent/Dockerfile installs the CLI with:

RUN npm install -g npm@latest && \
    npm install -g @anthropic-ai/claude-code@2.1.191 && \
    ...

@anthropic-ai/claude-code downloads its ~236 MB native binary in a postinstall script (node install.cjs). Recent npm versions block package lifecycle scripts by default, emitting:

npm warn install-scripts 1 package had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts   @anthropic-ai/claude-code@2.1.191 (postinstall: node install.cjs)

Because npm install -g npm@latest floats to whatever npm is newest at build time, the moment that default flipped, the postinstall stopped running and the image began shipping the stub /usr/bin/claude (which just prints Error: claude native binary not installed.). Exec-ing it yields the Exec format error.

This is a build-environment regression, not a code change — an image built a few hours earlier (before the npm default flipped) contained the real 236 MB ELF binary.

Expected behavior

The agent image contains the real, executable claude native binary; tasks run normally.

Proposed fix

  1. Explicitly allow the claude-code postinstall (npm's own suggested remedy):
    npm install -g --allow-scripts=@anthropic-ai/claude-code @anthropic-ai/claude-code@2.1.191
  2. Add a build-time guard RUN step that fails the build loudly if claude is ever the stub again (size check + claude --version), so a future npm/packaging change can't silently ship a broken runtime that only fails at task time.

Verification

  • Isolated build with the flag: claude resolves to a 236 MB ELF and claude --version2.1.191 (Claude Code). Without it: 500-byte stub.
  • Deployed to backgroundagent-dev and re-ran a Jira-triggered task end-to-end — task runs past turn 0.

Out of scope

  • Pinning npm to a fixed version (separate reproducibility hardening; can follow up).

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions