fix(agent): re-run install.cjs after npm update in Dockerfile#613
fix(agent): re-run install.cjs after npm update in Dockerfile#613fibanez wants to merge 1 commit into
Conversation
Claude Code 2.1.x ships native binaries via postinstall. The npm update step that patches transitive deps overwrites bin/claude.exe back to the fallback stub, causing 'Exec format error' at runtime. Re-run install.cjs to restore the native binary after the update.
f5c59dd to
0190103
Compare
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #613 +/- ##
=======================================
Coverage ? 89.30%
=======================================
Files ? 224
Lines ? 54356
Branches ? 5719
=======================================
Hits ? 48544
Misses ? 5812
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
isadeks
left a comment
There was a problem hiding this comment.
Review — and yes, this overlaps with two other open PRs
The fix itself is correct: npm update re-extracts the package's bin entry over the placeholder stub and npm doesn't re-run postinstall on update, so appending node install.cjs restores the native binary. Diagnosis matches main's Dockerfile exactly, CI is green, and it's a minimal 2-line change. I verified install.cjs exists in @anthropic-ai/claude-code@2.1.191 and is idempotent (re-running it when the binary is already correct is harmless). One caveat on my verification: on linux/amd64 I couldn't reproduce the npm update clobber (the binary stayed ELF) — the clobber looks arch-specific to the arm64 AgentCore image, which matches both this PR and #597 reporting it as live-caught on the deployed image, so I can't independently confirm the failure trigger, only that the fix is safe.
The overlap you'd want to resolve before merging any of these — three open PRs touch this exact issue:
| PR | Layer | Exec-format handling |
|---|---|---|
| #613 (this) | agent/Dockerfile |
+ node install.cjs |
| #597 | agent/Dockerfile + more |
+ node install.cjs && claude --version |
| #599 | error-classifier.ts |
adds the pattern that labels the runtime error |
- #597 is a strict superset of this PR on the Dockerfile line — it adds the identical
install.cjsstep plus&& claude --version, which hard-gates the image build (a broken shim failsdocker build, instead of every task dying at runtime). That build-time assertion is strictly better than restoring-and-hoping. #597 also carries a code comment explaining the shim mechanism. - #613 and #597 edit the same
RUN … npm --prefix update …line, so they will textually conflict — both can't merge as-is. - #599 is complementary, not a conflict — it classifies the same
Exec format errorinto a user-facing "Couldn't start the coding agent (environment issue)" (disjoint file). Prevention (#613/#597) + legibility (#599) are the two halves of ABCA-659; ideally both land.
Recommendation: fold this into #597's version (the && claude --version hard-gate) rather than merging #613 separately, then close #613 as superseded — unless #597 is blocked by its stack (it's stacked on #596 → #503; #503 merged, #596 still open). If #597 is going to sit behind that stack for a while and the exec-format break is hurting people now, the pragmatic call is to merge this (it's clean against main) and have #597 drop its Dockerfile hunk on rebase. Either way, please add the && claude --version build-time gate here so a future silent postinstall fallback fails the build, not the fleet — that's the one substantive thing #597 has that this doesn't.
(Flagging the overlap rather than re-reviewing the mechanics of all three; happy to review #597 in full — it also has a build-timeout classifier + failing-line log surfacing worth a look.)
Summary
install.cjs) that hardlinks the platform-specific binary over a placeholder stub atbin/claude.exe.npm --prefix updatestep (which patches vulnerable transitive deps inside the global@anthropic-ai/claude-codeinstall) re-extracts the package's bin entry, overwriting the native binary with the stub script. npm does not re-run postinstall duringupdate, so the binary is never restored.OSError: [Errno 8] Exec format error: 'claude'node "${CLAUDE_NPM_ROOT}/install.cjs"to the Dockerfile's npm install layer so the native binary is re-placed after the update step.Test plan
claude --versionreturns2.1.191 (Claude Code)backgroundagent-devstack in us-west-2