claude-code - 💡(How to fix) Fix postinstall strips Mach-O code signature on darwin-arm64 → macOS SIGKILLs claude on launch [2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#52746Fetched 2026-04-24 10:40:43
View on GitHub
Comments
2
Participants
3
Timeline
6
Reactions
0
Timeline (top)
labeled ×4commented ×2

Root Cause

Root cause (diagnosed)

Fix Action

Fix / Workaround

Happy to test patches against my env if useful.

RAW_BUFFERClick to expand / collapse

Environment

  • macOS Darwin 25.2.0 (Apple Silicon, arm64)
  • Node v20.19.6, npm global install via Homebrew prefix (`/opt/homebrew/lib/node_modules`)
  • Claude Code installed globally: `@anthropic-ai/claude-code`

Symptom

After an auto-update, `claude` is killed immediately on launch:

``` ~ ❯ claude [1] 90529 killed claude ```

Root cause (diagnosed)

The native binary at `@anthropic-ai/claude-code/bin/claude.exe` loses its code signature during the postinstall. macOS kernel then SIGKILLs it on exec.

``` $ codesign -dv /opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe ...: code object is not signed at all ```

The platform-native package under `node_modules/@anthropic-ai/claude-code-darwin-arm64/` kept its signed copy:

``` $ codesign -dv .../claude-code-darwin-arm64/claude Identifier=com.anthropic.claude-code Format=Mach-O thin (arm64) CodeDirectory v=20500 size=1654533 flags=0x10000(runtime) Signature size=9046 ```

So the signature exists on the source binary but is missing on the destination after `install.cjs` writes it to `bin/claude.exe`.

On this install the postinstall had also left `bin/claude.exe` as the ASCII fallback stub ("Native package … not found"), because the `package.json` of `claude-code-darwin-arm64` was missing from `node_modules` (only the `claude` binary remained). `require.resolve('@anthropic-ai/claude-code-darwin-arm64/package.json')` in `install.cjs:144` then failed, so the real binary was never copied at all. A retained staging copy at `@anthropic-ai/.claude-code-*/` had the complete package.

Reproduction sketch

  1. Fresh `npm i -g @anthropic-ai/claude-code` on Apple Silicon.
  2. Trigger an auto-update (or any subsequent upgrade).
  3. Observe that `bin/claude.exe` is either (a) the ASCII fallback stub, or (b) a Mach-O binary that reports "not signed at all" to `codesign -dv`.
  4. `claude` → SIGKILL.

Manual fix that worked

```bash src=/opt/homebrew/lib/node_modules/@anthropic-ai/.claude-code-<hash>/node_modules/@anthropic-ai/claude-code-darwin-arm64/claude dst=/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe rm -f "$dst" && /bin/cp "$src" "$dst" && chmod +x "$dst" codesign -dv "$dst" # signature preserved ```

Suggested fixes

  1. Preserve code signatures: `install.cjs` should use a copy method that preserves extended attributes and code signing (e.g. `fs.copyFileSync` with COPYFILE_FICLONE, or `cp -c` via spawn). If the current impl does a `fs.writeFileSync(fs.readFileSync(...))` round-trip, that loses the signature.
  2. Ad-hoc re-sign as a fallback: if signature preservation isn't feasible across copy paths, have the postinstall do `codesign --force --sign - <dst>` after the copy on darwin. Ad-hoc signing is enough to stop the kernel killing it.
  3. Verify after install: add a `codesign -v` check at the end of `install.cjs` on darwin and bail loudly if the destination is unsigned, instead of leaving the user with a silently-broken install.
  4. Preserve package.json when overwriting optional dep dirs: something in the upgrade path stripped `package.json`/`LICENSE`/`README` from `claude-code-darwin-arm64`, which was the original reason `install.cjs` fell back to the stub. Worth investigating whether an atomic rename vs file-by-file overwrite would help.

Happy to test patches against my env if useful.

extent analysis

TL;DR

The most likely fix is to modify the install.cjs script to preserve code signatures when copying the binary, using a method like fs.copyFileSync with COPYFILE_FICLONE or cp -c via spawn.

Guidance

  • Verify that the install.cjs script is using a method that preserves extended attributes and code signing when copying the binary.
  • Consider adding a codesign -v check at the end of install.cjs on Darwin to ensure the destination binary is signed.
  • Investigate why the package.json file is being stripped from the claude-code-darwin-arm64 directory during the upgrade path.
  • Test the suggested fixes, such as using fs.copyFileSync or cp -c, to ensure the code signature is preserved.

Example

// In install.cjs, use fs.copyFileSync with COPYFILE_FICLONE to preserve code signature
const src = '/opt/homebrew/lib/node_modules/@anthropic-ai/.claude-code-<hash>/node_modules/@anthropic-ai/claude-code-darwin-arm64/claude';
const dst = '/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe';
fs.copyFileSync(src, dst, fs.constants.COPYFILE_FICLONE);

Notes

The issue is specific to the claude-code package on Apple Silicon with Node v20.19.6, and the suggested fixes may not apply to other environments or versions.

Recommendation

Apply the workaround by modifying the install.cjs script to preserve code signatures when copying the binary, as this is the most direct and effective solution to the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix postinstall strips Mach-O code signature on darwin-arm64 → macOS SIGKILLs claude on launch [2 comments, 3 participants]