Claude Codeの終了コード1・3・137:原因を数字だけで決めない
Claude Codeの「process exited with code 1/3/127/137」エラーを原因別に整理。認証競合・Windows特有のクラッシュ・OOM・新設定sandbox.network.strictAllowlistまで、切り分け手順つきで解説する。
エンジニアのゆとです。
「Claude Code process exited with code 1」。
このエラー文でここに来た人は、たぶんもう数分イライラしてる。自分もXでこの手のエラー報告を見るたびに「あ、また出たか」と思うんだけど、正直このメッセージ自体は何も教えてくれない。code 1もcode 3もcode 127も、Claude Codeがバックグラウンドプロセスとして落ちたときに表示される「死亡診断書の1行目」でしかなくて、原因は毎回別物だ。
気になって、GitHub Issueをこの手のエラーで検索してみたら、同じ「exited with code」の報告が数十件出てきた。原因は認証の設定不備からWindows特有のクラッシュ、メモリ不足、直近追加されたサンドボックスのネットワーク設定まで、見事にバラバラだった。
この記事は、その報告を全部読んで「exit codeの数字ごとに何が起きているか」を切り分けたものだ。自分の環境で全部を再現できたわけじゃないので、そこは正直に書く。ただ、どの原因がどのcodeに紐づきやすいかは公式ドキュメントとIssueの実例で裏を取ってある。
まず確認すること — exit codeは「何が」ではなく「どう」死んだかしか教えない
Claude Codeはbunでコンパイルされたバイナリとして動いている。このバイナリがクラッシュしたりOSに強制終了させられたりすると、親プロセス(CLI本体やVS Code拡張、Desktopアプリ)が「process exited with code N」というメッセージを表示する。
まず、どのプロセスが、どの起動元を通して返した数字かを確認します。Bashはシグナルで終了した子を通常「128 + シグナル番号」で表しますが、アプリ自身も137などの値を返せます。したがって、数字の大小だけでは自己終了とシグナル終了を区別できません。下表はBash型の表示で調べる候補であり、Claude Code全環境に共通する原因一覧ではありません。
| exit code | 意味 | よくある原因 |
|---|---|---|
| 1 | 汎用エラー(プロセス自身が異常終了) | 認証競合、利用規約未同意、破損したセッションファイル |
| 3 | アプリ・起動元固有の終了コード | 数字だけでは原因不明。後述のWindows報告は一例 |
| 126 | コマンドは見つかったが実行できない | 実行権限がない、shebangが壊れたフックスクリプト |
| 127 | コマンドが見つからない | PATHが通っていない、依存バイナリ未インストール |
| 137 | Bash型表示ならSIGKILL(128+9)の候補 | 明示的な終了、制限、OOMなどを別の記録で確認。137だけでは確定しない |
| 139 | Bash型表示ならSIGSEGV(128+11)の候補 | クラッシュログと起動元の表示仕様を確認 |
| 143 | Bash型表示ならSIGTERM(128+15)の候補 | CIのキャンセル・タイムアウト記録などと照合 |
2026年10月16日訂正: 旧版の「128以上ならOS側、128未満ならアプリ側」という断定を撤回しました。以下の隔離した子プロセス検証では、異なる終了理由が同じ137として表示されました。
同じ137でも終了理由が違う:ローカル検証
2026年10月16日、macOS上で、検証用Python子プロセスだけを使って3ケースを確認しました。Claude Codeの実クラッシュやメモリ枯渇を再現した検証ではありません。
| 検証用の子プロセス | Pythonで直接待った戻り値 | Bashが表示した子の終了値 |
|---|---|---|
自分でsys.exit(137)を実行 | 137 | 137 |
| 自分自身へSIGKILLを送信 | -9 | 137 |
自分でsys.exit(3)を実行 | 3 | 3 |
Python公式のreturncode仕様では、POSIXでシグナル終了した子は負のシグナル番号になります。Bashの終了ステータス仕様とは表示方法が異なります。ログの数字を読む前に、どの層の戻り値かを確かめてください。
137が出ただけでメモリ増設、有料プラン変更、認証のやり直しへ進む必要はありません。OOMならメモリ使用量やコンテナの終了理由、タイムアウトなら実行基盤の制限やキャンセル記録と照合します。根拠がなければ原因は未確定のままにします。ログを共有する際は、キー・トークン・個人情報を除去してください。
code 1 — 認証・規約・セッションも確認候補
以下は確認候補の例で、発生割合を測定したものではありません。code 1だけで原因をこの3つに限定せず、直前のエラーと起動元のログを先に確認してください。
パターン1: APIキーとOAuthトークンの競合
環境変数ANTHROPIC_API_KEYが残ったままの状態で/loginのOAuth認証を通すと、環境変数側が優先されて認証情報がねじれる。結果、内部で認証エラーが起きてプロセスごと落ちる。
# 環境変数を確認
if [ "${ANTHROPIC_API_KEY+x}" = x ]; then
printf 'ANTHROPIC_API_KEY: set (value hidden)\n'
else
printf 'ANTHROPIC_API_KEY: unset\n'
fi
# 残っていたら一旦クリアしてから再ログイン
unset ANTHROPIC_API_KEY
claude auth logout
claude auth login
.zshrcや.bashrcに古いAPIキーがexportされたまま残っているケースが多い。シェルの設定ファイルも合わせて確認したほうがいい。
パターン2: 利用規約・ポリシーの未同意
アップデート直後にこのエラーが出た場合、ブラウザでclaude.aiにログインして保留中の利用規約更新に同意していないだけ、というオチが意外と多い。JP圏の実例でも、この一手で直った報告が複数見つかった。
対処は単純で、ブラウザでclaude.aiを開いてログインし、規約同意のダイアログが出ていないか確認してからClaude Codeを再起動する。
パターン3: 破損したセッションファイル
~/.claude/配下のセッション状態ファイルが壊れていると、起動直後にクラッシュループへ入ることがある。セッション履歴を保持したまま復旧を試みたい場合は/resumeまわりの仕様を先に把握しておくと当たりをつけやすい。

それでも直らない場合は、~/.claude/配下を退避してから空の状態で起動し直すのが最終手段になる。ただし設定やhistoryも消えるので、退避(rename)であって削除ではない、という順番を守ったほうがいい。
code 3 — 数字ではなく、同時に出たクラッシュログを読む
code 3をWindows固有やセグメンテーション違反の共通コードとみなすことはできません。旧版で取り上げたWindowsの報告例では、panic(main thread): Segmentation faultという形でbunランタイム自体がクラッシュしていた。
Claude Code process exited with code 3
============================================================
Bun v1.3.14 Windows x64
panic(main thread): Segmentation fault at address 0x40FE0
panic: Segmentation fault at address 0x1DF3ECBFFE8
panicked during a panic. Aborting.
これはアプリ側のロジックエラーというより、コンパイル済みバイナリの実行時クラッシュに近い。自分で回避策をひねり出せる類のバグではないので、現実的な対処は次の3つになる。
- Claude Codeを最新版に更新する(
claude --versionで確認し、古ければclaude update) - 一時的にWSL2上でCLI版を動かして症状が消えるか確認する(Windowsネイティブ版特有の問題かどうかの切り分けになる)
- 症状が再現するなら、上のログをそのままGitHub Issueに貼って報告する(同じスタックトレースの報告が集まるほど優先度が上がる)
Windows環境そのもので消耗したくない人は、そもそもの開発環境をどう組むかを見直す選択肢もある。

code 126 / 127 — PATHとフックスクリプトの権限
この2つはExit code自体の意味がはっきりしている分、原因も絞りやすい。
code 127は「コマンドが見つからない」。Claude Code本体というより、hooksやカスタムコマンドから呼び出している外部コマンド(jq、rg、独自スクリプトなど)がPATH上にない場合に出る。.claude/settings.jsonのhooksでコマンドを直書きしている人は、そのコマンドが今のシェル環境でwhich <コマンド名>で見つかるか確認するのが一番早い。
code 126は「コマンドはあるが実行できない」。フックスクリプトに実行権限(chmod +x)が付いていない、またはシバン行(#!/bin/bashなど)が壊れているケースが典型だ。
# フックスクリプトの実行権限を確認
ls -la .claude/hooks/
# 権限がなければ付与
chmod +x .claude/hooks/*.sh
hooksまわりの設計自体を見直したい場合は、そもそもどう組むのが安全かをまとめた記事がある。

code 137 / 139 / 143 — シグナルで強制終了されたパターン
137・139・143は、起動元がBash型のシグナル表示をしている場合に手がかりになります。アプリが同じ値を明示的に返す場合もあるため、終了理由の記録を併せて確認します。
code 137で調べる候補の一つは、メモリ不足によるOOMの介入です。この数字だけで頻度や原因を断定することはできません。特にDockerコンテナ内やメモリ制限のあるCI環境でClaude Codeを長時間走らせていると、コンテキストが膨らむにつれてメモリ使用量が増え、上限に達した瞬間にOSへ強制的に落とされる。Mac上のDocker環境でこの手のメモリ枯渇に遭遇したことがある人は、そもそもの割り当て設計を見直したほうが早い。
長時間セッションでメモリ以外の要因からプロセスが不安定になる話は、以前実測データで解剖したことがある。フリーズや幻聴的な挙動まで含めて、コンテキストがどう自壊していくかを知りたい人はこちらを読んでおくと関連が見える。

code 139がBash型のシグナル表示なら、SIGSEGVによる終了を疑います。code 3のケースと近く、bunランタイムやネイティブ依存のクラッシュが疑わしい。再現性があるなら最新版への更新とWSL2での切り分けが有効なのは code 3と同じだ。
code 143がBash型のシグナル表示なら、SIGTERMによる終了を疑います。意図した停止か事故かは、この数字だけでは分かりません。GitHub Actionsのタイムアウト、CIのジョブキャンセル、killコマンドの誤爆などが典型で、Claude Code自体のバグを疑う前に、まず自分が使っているCI/CDの設定側でタイムアウト値やキャンセル条件を確認したほうがいい。
見落とされがちな原因 — sandbox.network.strictAllowlistがMCPサーバーを黙って落としているケース
ここが今回一番書いておきたかった話で、7月末に追加された比較的新しい設定が関係している。
Claude Codeのサンドボックスにはsandbox.network.strictAllowlistという設定があり、有効にすると許可リスト外のドメインへの通信をプロンプトなしで即座に拒否する。

この設定自体は便利で、無人実行の途中でプロンプト待ちのまま止まる事故を防ぐために追加されたものだ。ただし、MCPサーバーが起動時に外部APIへ疎通確認のリクエストを飛ばす設計になっている場合、許可リストにそのドメインが入っていないと、MCPサーバー側が起動直後に接続エラーで落ちる。そのMCPサーバーの異常終了に引きずられる形で、Claude Code本体のプロセスまでexited with code 1を返すことがある。
実際、GitHub Issueには「ネットワークサンドボックスがMCPサーバーの外向き通信をブロックして、tavily-mcpのようなHTTP通信を伴うMCPサーバーが動かなくなった」という報告や、「VMのネットワーク許可リストにブロックされてセッションがフリーズした」という報告が上がっている。エラーメッセージだけを見ると認証エラーやプロセスクラッシュに見えるので、この設定を有効にした心当たりがある人は、まずここを疑ったほうが早い。
対処はシンプルで、使っているMCPサーバーが通信するドメインを把握して、allowedDomainsに明示的に追加すること。
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["github.com", "*.npmjs.org", "api.your-mcp-provider.com"],
"strictAllowlist": true
}
}
}
自作のMCPサーバーを使っている場合は、そのサーバーの設定・ネットワーク要件から見直しておくと同じ問題を繰り返さずに済む。

GitHub Actions上の「exit code 1」はローカルのそれとは別物
もう一つ、検索してこの記事に来た人の一部が混同していそうな話を書いておく。
GitHub Actionsのワークフローログに出る「Error: Process completed with exit code 1」は、Claude Code本体が異常終了したという意味ではなく、ワークフロー内で実行したコマンド(Claude Codeを呼び出すステップを含む)が非ゼロの終了コードを返した、というActions側の一般的な失敗表示だ。
原因はAPIキーやシークレットの設定ミス、GitHub App側の権限不足など、ローカルCLIのクラッシュとは違う話であることが多い。CI/CD上でClaude Codeを運用する設計そのものを詰めたい場合は、ワークフロー全体の組み方を先に見ておくと切り分けが早くなる。

切り分けの手順
原因候補が多いエラーほど、闇雲に試すより順番を決めて潰したほうが早い。自分ならこの順番で確認する。
- 数字とともに、終了したコマンド、起動元、OS、直前のログを確認する。128との大小だけで原因を分類しない
claude --versionでバージョンを確認し、最新でなければclaude updateしてから再現するか試す- ブラウザでclaude.aiにログインし、利用規約・ポリシー同意の保留がないか確認する
- 環境変数
ANTHROPIC_API_KEYが残っていないか確認する - MCPサーバーを使っているなら、一旦すべて無効化した状態で再現するか試す(
claude mcp listで現在の登録状況を確認できる) - サンドボックスのネットワーク設定を有効にしているなら、
allowedDomainsの設定を見直す - hooksを設定しているなら、実行権限とPATHを確認する
- ここまでで直らなければ、エラーログ全文とOS・バージョン情報を添えてGitHub Issueに報告する
権限プロンプトの出方そのものを見直したい人は、根本的に確認・承認フローの設計を変える選択肢もある。

結局、exit codeは「調べ方の入口」でしかない
書いてて思ったけど、このエラーメッセージがすること自体は「死んだ」という事実の通知だけで、原因の特定は結局人間側の仕事になる。数字ごとの傾向は今回まとめた通りだけど、Claude Code自体が高頻度でアップデートされているツールである以上、この対応表も半年後には古くなっている可能性が高い。
一番確実なのは、エラーが出た瞬間のログを丸ごと保存しておく癖をつけることだと思う。バージョン番号、OS、直前に何をしていたか。この3点セットがあれば、GitHub Issueで同じ報告をしている人を見つけやすくなるし、自分で切り分けるときの手がかりにもなる。
公式のトラブルシューティング情報は随時更新されているので、最終的にはこちらも一度は目を通しておいたほうがいい。