Claude Code のエラーログはどこに残るか——4種類を起こして全部調べた

目次
  1. 検証方法: 本物の ~/.claude を触らないよう偽のHOMEを向ける
  2. stderr だけで消えるエラーと、transcript に残るエラー
  3. MCP サーバーの起動失敗は Caches 配下の専用ログに残る
  4. 破損した .claude.json は1回だけエラーを出して自己修復する
  5. 画面に1行しか出ないエラーの原因行は --debug-file でしか取れない
  6. エラーを踏んでからでも追えるもの、追えないもの

Claude Code でエラーに当たったとき、画面に出るのはせいぜい1行だ。原因を追うにはログを探すしかないが、「エラーログ」は1箇所にまとまっていない。stderr だけで消えるエラーがある一方で、セッション記録・キャッシュ・バックアップと、種類ごとに残る場所がバラバラだった。

今回は ~/.claude 相当を丸ごと隔離した偽のHOMEで、4種類のエラーを実際に起こし、ディスクに何が残るかを全部洗った。

検証方法: 本物の ~/.claude を触らないよう偽のHOMEを向ける

環境は Claude Code 2.1.267 / macOS 26.6.1 / arm64。

$ sh -c 'claude --version; sw_vers; uname -m'
2.1.267 (Claude Code)
...
arm64
# exit=0 (19 ms)

測り方は単純で、HOME を作業ディレクトリ内の fakehome/ に差し替えて claude を実行するだけだ。~/.claude・~/.claude.json・~/Library/Caches が全部 fakehome 配下に作られるので、実行後に find すれば「どこに何が書かれたか」がそのまま見える。認証は --bare で keychain も OAuth も読ませず、ANTHROPIC_API_KEY も渡さない。つまり API キー無しの状態で、認証失敗が確定的に起きる。実際の API コールと課金は発生しない設計にした。

stderr だけで消えるエラーと、transcript に残るエラー

まず一番単純なエラーから。存在しないオプションを渡す。

$ sh -c 'touch fakehome/.marker; env HOME=$PWD/fakehome claude --definitely-not-a-real-flag 2>&1; echo "exit=$?"; find fakehome -newer fakehome/.marker -type f | wc -l'
error: unknown option '--definitely-not-a-real-flag'
exit=1
       0
# exit=0 (62 ms)

error: unknown option が出て exit 1。そして fakehome 内で新しく作られたファイルは 0 件だ。つまり使い方エラーは stderr に出るだけで、どのファイルにも残らない。画面を閉じた時点で証跡は消える。

次に認証失敗。API キー無しで claude -p を投げる。

$ sh -c 'env -u ANTHROPIC_API_KEY HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude --bare -p "hi" --output-format json 2>&1; echo "exit=$?"'
...
exit=1
# exit=0 (230 ms)

stdout の JSON(1行なので省略した)には "is_error":true と "terminal_reason":"api_error"、"result":"Not logged in · Please run /login" が入る一方、"subtype":"success" でもある。この「エラーなのに success」という出力自体は既刊の記事で扱ったのでここでは割愛する。今回の本題はその先で、この失敗した実行がディスクにファイルを残していたことだ。

$ sh -c 'find fakehome -type f | sed -e "s|projects/[^/]*/|projects/<cwd>/|" | sort'
fakehome/.claude.json
fakehome/.claude/backups/.claude.json.backup.1790860072178
fakehome/.claude/projects/<cwd>/49c3fd91-f5f2-4558-9cdf-536427a61b84.jsonl
fakehome/.marker
# exit=0 (8 ms)

~/.claude/projects/<cwd>/<session-id>.jsonl — これがセッション記録(transcript)だ。中身を見ると、エラーの応答が assistant 行として記録されていた。

$ python3 -c 'import json,glob; [print(json.dumps({k:d.get(k) for k in ('"'"'type'"'"','"'"'isApiErrorMessage'"'"','"'"'error'"'"','"'"'subtype'"'"')},ensure_ascii=False)) for f in glob.glob('"'"'fakehome/.claude/projects/*/*.jsonl'"'"') for l in open(f) for d in [json.loads(l)] if d.get('"'"'isApiErrorMessage'"'"')]'
{"type": "assistant", "isApiErrorMessage": true, "error": "authentication_failed", "subtype": null}
# exit=0 (18 ms)

isApiErrorMessage:true と error:"authentication_failed" が付いている。つまり認証・API系の失敗は transcript に残る。-p でも1回の実行ごとに JSONL ファイルが作られるので、「さっきの失敗、あとで見返したい」が transcript を辿ればできる。実際、今回の一連の失敗実行だけで projects/ 配下には transcript が4本・計11行できていた(verify/logs/020-transcript-count.txt)。

MCP サーバーの起動失敗は Caches 配下の専用ログに残る

存在しないコマンドを叩く MCP サーバー broken-fs を user スコープに登録した。

$ sh -c 'env HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude mcp add broken-fs --scope user -- nonexistent-mcp-cmd-xyz --serve 2>&1; echo "exit=$?"'
Added stdio MCP server broken-fs with command: nonexistent-mcp-cmd-xyz --serve to user config
...
exit=0
# exit=0 (115 ms)

claude mcp list でヘルスチェックすると案の定失敗する。

$ sh -c 'env HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude mcp list 2>&1; echo "exit=$?"'
Checking MCP server health…

broken-fs: nonexistent-mcp-cmd-xyz --serve - ✘ Failed to connect — ENOENT: Executable not found in $PATH: "nonexistent-mcp-cmd-xyz"
exit=0
# exit=0 (154 ms)

なお失敗していても mcp list 自体は exit=0 で返る。スクリプトで異常を検知したいなら終了コードではなく出力を見る必要がある。この失敗は画面表示だけではなく、~/Library/Caches/claude-cli-nodejs/<プロジェクト>/mcp-logs-<サーバー名>/<タイムスタンプ>.jsonl という専用の場所にファイルとして残る。中身はこうだ。

$ python3 -c 'import json,glob; [print(json.dumps({k:v for k,v in json.loads(l).items() if k!='"'"'cwd'"'"'},ensure_ascii=False)) for f in glob.glob('"'"'fakehome/Library/Caches/claude-cli-nodejs/*/mcp-logs-*/*.jsonl'"'"') for l in open(f)]'
{"debug": "Starting connection with timeout of 30000ms", "timestamp": "2026-10-01T13:08:49.620Z", "sessionId": "68a69608-d8ae-4f71-8907-d55768a149cf"}
{"debug": "Connection failed after 4ms (ENOENT): Executable not found in $PATH: \"nonexistent-mcp-cmd-xyz\"", "timestamp": "2026-10-01T13:08:49.623Z", "sessionId": "68a69608-d8ae-4f71-8907-d55768a149cf"}
{"error": "Connection failed (ENOENT): Executable not found in $PATH: \"nonexistent-mcp-cmd-xyz\"", "timestamp": "2026-10-01T13:08:49.623Z", "sessionId": "68a69608-d8ae-4f71-8907-d55768a149cf"}
# exit=0 (18 ms)

接続開始・失敗までの時間・エラー本文が JSONL で記録されている。MCP サーバーが「つながらない」だけで詳細が分からないとき、真っ先に見るべきはこの mcp-logs 配下だ。

破損した .claude.json は1回だけエラーを出して自己修復する

fakehome/.claude.json をわざと壊した({ "mcpServers": BROKEN2 という文法違反)状態で -p を実行すると、画面には詳しいエラーが出て exit 1 で止まる。

$ bash -c 'env -u ANTHROPIC_API_KEY HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude --bare -p "hi" 2>&1 | sed "s|$PWD|<cwd>|g"; echo "exit=${PIPESTATUS[0]}"'

Claude configuration file at <cwd>/fakehome/.claude.json is corrupted: JSON Parse error: Unexpected identifier "BROKEN2"
The corrupted file has been backed up to: <cwd>/fakehome/.claude/backups/.claude.json.corrupted.1790860292773
...
exit=1
# exit=0 (96 ms)

ここで重要なのは次の実行だ。もう一度同じコマンドを打つと、破損のエラーはもう出ない。

$ bash -c 'env -u ANTHROPIC_API_KEY HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude --bare -p "hi" 2>&1 | sed "s|$PWD|<cwd>|g"; echo "exit=${PIPESTATUS[0]}"'
Not logged in · Please run /login
exit=1
# exit=0 (168 ms)

破損したファイルは ~/.claude/backups/.claude.json.corrupted.<タイムスタンプ> に退避され、本体は再生成されていた。つまりこのエラーの詳細表示は初回の1回きりで、2回目以降は何事もなかったかのように進む。あとから「さっき .claude.json が壊れていたはず」と追えるのは backups 配下に残った .corrupted.* と .backup.* のファイルだけだ。

画面に1行しか出ないエラーの原因行は --debug-file でしか取れない

ここまでで残るもの・残らないものが見えてきたが、もう一段階ある。同じ認証失敗を --debug-file 付きで実行すると、画面には同じ1行しか出ないのに、指定したファイルに 73 行のログが書かれた。

$ sh -c 'env -u ANTHROPIC_API_KEY HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude --bare --debug-file dbg.log -p "hi" 2>&1; echo "exit=$?"; wc -l dbg.log'
Not logged in · Please run /login
exit=1
      73 dbg.log
# exit=0 (158 ms)

--debug-file は付けるだけでデバッグモードも有効になる。出力先を指定しない --debug 単体なら、既定では ~/.claude/debug/<session-id>.txt に書かれる(CLI リファレンス)。

$ sh -c 'env -u ANTHROPIC_API_KEY HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude --bare --debug -p "hi" >/dev/null 2>&1; echo "exit=$?"; find fakehome/.claude/debug -type f 2>/dev/null | sed "s|fakehome/.claude/debug/||"; wc -l fakehome/.claude/debug/*.txt 2>/dev/null | tail -3'
exit=1
bb06c81a-fabd-483c-8abe-d3cdea6e0f0b.txt
      73 fakehome/.claude/debug/bb06c81a-fabd-483c-8abe-d3cdea6e0f0b.txt
# exit=0 (174 ms)

この 73 行の中に [ERROR] 行が 5 行あり、画面の「Not logged in」では見えなかった原因行が入っていた。

$ sh -c 'grep -c "\[ERROR\]" dbg.log; grep -E "API error|Error in API request|invalid_api_key" dbg.log'
5
2026-10-01T13:09:21.111Z [ERROR] API error (attempt 1/11): Could not resolve authentication method. Expected one of apiKey, authToken, credentials, config, or profile to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted
2026-10-01T13:09:21.120Z [ERROR] Error in API request: Could not resolve authentication method. Expected one of apiKey, authToken, credentials, config, or profile to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted
2026-10-01T13:09:21.120Z [ERROR] API error x-client-request-id=3b0e12e5-302a-4bc7-9731-7b1e7d41eadd (give this to the API team for server-log lookup)
2026-10-01T13:09:21.120Z [ERROR] API invalid_api_key: [REDACTED] not resolve authentication method. Expected one of apiKey, authToken, credentials, config, or profile to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted
# exit=0 (7 ms)

Could not resolve authentication method — 画面の1行と transcript の authentication_failed のさらに下の、認証メソッドが解決できなかったという根本原因はここにしか書かれていない。リクエストをサーバー側で追うための x-client-request-id も同様だ。なお [ERROR] 行は 5 行のうち残り 1 行が ps の EPERM で、これはこの検証を動かしたサンドボックス環境由来のものだ。逆に言えば、ユーザーに見えない内部エラーまで全部ここに出る。

厄介なのは、デバッグログは実行時に有効化しておかないと取り返しがつかないことだ。今回の一連の実行で ~/.claude/debug/ に残ったのは --debug 付きの1セッション分だけで、何も付けずに失敗した実行分は存在しない。再現できるエラーなら --debug-file 付きで叩き直すのが確実で、再現しにくいエラーに備えるなら常用しておく選択肢になる。

補助として claude doctor も非対話で動き、インストール方式・認証・環境の診断を出してくれた(この環境では keychain 書き込み不可の警告が出たが、これもサンドボックス由来だ)。

$ bash -c 'perl -e "alarm 20; exec @ARGV" env HOME=$PWD/fakehome CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 claude doctor 2>&1 | sed "s|$PWD|<cwd>|g" | head -40; echo "exit=${PIPESTATUS[0]}"'
Claude Code doctor

Running: npm-global (2.1.267)
Commit: a9e1808c8204
Platform: darwin-arm64
...
1 warning found
...
For a full setup checkup that can also fix issues, run /doctor in a Claude Code session.
exit=0
# exit=0 (281 ms)

エラーを踏んでからでも追えるもの、追えないもの

一通り起こしたあとの fakehome の中身がこれだ。

$ sh -c 'find fakehome -type f | sed -e "s|projects/[^/]*/|projects/<cwd>/|" -e "s|claude-cli-nodejs/[^/]*/|claude-cli-nodejs/<proj>/|" | sort'
fakehome/.claude.json
fakehome/.claude/backups/.claude.json.backup.1790860072178
fakehome/.claude/backups/.claude.json.backup.1790860214286
fakehome/.claude/backups/.claude.json.backup.1790860292785
fakehome/.claude/backups/.claude.json.corrupted.1790860214273
fakehome/.claude/backups/.claude.json.corrupted.1790860292773
fakehome/.claude/debug/bb06c81a-fabd-483c-8abe-d3cdea6e0f0b.txt
fakehome/.claude/projects/<cwd>/49c3fd91-f5f2-4558-9cdf-536427a61b84.jsonl
fakehome/.claude/projects/<cwd>/bb06c81a-fabd-483c-8abe-d3cdea6e0f0b.jsonl
fakehome/.claude/projects/<cwd>/d2b800a5-9daf-45e0-91dd-a97cdb93d6c6.jsonl
fakehome/.claude/projects/<cwd>/f70a15a1-a18e-49a0-87af-652149f7483c.jsonl
fakehome/.marker
fakehome/.npm/_logs/2026-10-01T13_11_02_112Z-debug-0.log
fakehome/.npm/_logs/2026-10-01T13_11_02_198Z-debug-0.log
fakehome/Library/Caches/claude-cli-nodejs/<proj>/mcp-logs-broken-fs/2026-10-01T13-08-49-597Z.jsonl
# exit=0 (6 ms)
4filesprojects(transcript)5filesbackups1filesdebug1filesCaches(mcp-logs)
一連のエラー実験のあと偽HOME内に残ったファイル数

まとめると、エラーの種類ごとの「残る場所」はこうなる。

エラー 画面に出るもの 事後に残るファイル
使い方エラー(未知のフラグ) stderr の1行 なし
認証・API系の失敗 result の1行 ~/.claude/projects/<cwd>/*.jsonl(isApiErrorMessage 行)
MCP サーバー起動失敗 ✘ Failed to connect ~/Library/Caches/claude-cli-nodejs/*/mcp-logs-*/
.claude.json 破損 初回のみ詳細表示 ~/.claude/backups/.claude.json.corrupted.*
あらゆる内部エラー 見えない --debug / --debug-file 指定時のみ

(fakehome/.npm/_logs/ の2本は npm 経由の起動ログで、Claude Code 本体のエラー記録ではない。)

冒頭の問いへの答えはこうだ。事後に追えるのは transcript・mcp-logs・backups に残る種類だけで、stderr だけのエラーと --debug 無しの詳細原因は取り返せない。「エラーログはどこ」に1つの答えはなく、エラー1つずつに対して残る場所を上の表で引くのが実際の切り分け手順になる。

今回測っていない範囲も書いておく。課金ゼロで進めるため実際の API 応答エラー(5xx・429 など)は起こしておらず、transcript にどう記録されるかは未検証だ。パスも macOS のもので、Linux や CLAUDE_CONFIG_DIR 指定時の配置は別途確かめる必要がある(公式の設定ドキュメントに環境差の記載がある)。~/.claude/debug/ のログがどれくらいの期間残るかも、今回は測っていない。

関連書籍