Claude Codeにエラーを「直して」と言う前に:原因を当てさせる渡し方
Claude Codeにエラーを丸投げすると一般論が返る。ログの整え方、再現手順の作り方、スタックトレースの読み方を僕の失敗込みで具体的に。
赤い文字でエラーが10行流れてきた瞬間、僕はほぼ反射でこう打っていました。「これ直して」。
返ってきたのは、それっぽくて、なんの役にも立たない一般論です。「環境変数を確認してください」「型定義を見直してください」。いや、それが分からないから貼ってるんだよ、と画面に向かってつぶやいた回数は数えきれません。
問題はClaude Codeの頭の良さじゃありませんでした。僕の渡し方が雑だったんです。エラー文の外にある「直前に何をしたか」「どの環境で落ちたか」「期待していた結果」を、Claude Codeは自動では知りません。そこを埋めてやるだけで、回答は「推測」から「次に打つコマンド」に変わります。
この記事の要点
- Claude Codeにエラーを丸投げすると一般論が返る。ログを「再現できるバグ報告」に変換してから渡すのがコツ。
- エラーはほぼ「入力・環境・順序」の3つに分けられる。最初にどれかを聞くだけで調査が速くなる。
- スタックトレースは最後の行ではなく、最初のアプリ内フレームを見る。
node_modulesは機械的に削る。 - プロンプトに「confidence level(確信度)」と「証拠行を示せ」を入れると、ハルシネーション(それっぽい嘘)を弾ける。
- 修正後は落ちたコマンドをもう一度通す。これをやらない人がいちばん多い。
エラーを推測ではなく「再現」に変える
初心者がつまずくのは、エラー文が難しいからではありません。僕が何百回も自分でやらかしてきた失敗はこの3つです。
- ログの最後の数行だけ貼る(原因は中盤に埋まっているのに)
- 実行したコマンドを書かない
- 修正したあと、別のコマンドで「直ったつもり」になる
この3つをやめるだけで、Claude Codeの精度は体感で倍くらい変わります。やることはシンプルで、いつも同じ順番を固定するだけです。
- 失敗したコマンドの出力を、消す前にファイルへ保存する
- ログを短く整形する(全文は残す)
- Claude Codeに「答え」ではなく「仮説と再現手順」を依頼する
- 最小再現を作る
- 修正して、同じコマンドで検証する
- 再発防止を
CLAUDE.mdやテストに残す
公式の基本操作は Claude Code common workflows にまとまっています。困ったときの確認先は troubleshooting を見ておくと安心です。
エラーは「入力・環境・順序」の3つに分けられる
実務で出るエラーは、単独で起きるより「入力」「環境」「順番」のどれかと結びついて起きます。Claude Codeに貼る前にこの3分類で当たりをつけておくと、回答の検証が一気に楽になります。
1つ目は、入力の形が変わったケース。 APIのレスポンスから user.id が消えた、CSVの列名が変わった、任意項目が null で届くようになった、という類です。TypeScriptなら型エラーで気づけることもありますが、本番では Cannot read properties of undefined のような実行時エラーになって初めて発覚することも多い。Claude Codeには、エラー文に加えて「直前の入力例」「期待したデータ形」「実際のレスポンスの一部」を渡すと、型定義・バリデーション・UIの分岐のどこを直すべきか分けられます。
2つ目は、環境が違うケース。 ローカルでは通るのにCIで落ちる、開発では起動するのにKubernetesでは落ちる、という問題です。犯人はだいたい、Node.jsのバージョン、環境変数、タイムゾーン、ファイルパスの大文字小文字、Docker imageのビルド手順あたりに隠れています。「ローカルで成功したコマンド」と「CIまたはPodで失敗したコマンド」を並べて渡すと、コードの問題か環境差分かを切り分けやすくなります。
3つ目は、実行順序や非同期のケース。 await の付け忘れ、テストの並列実行で共有ファイルを壊す、migration前にアプリが起動する、外部APIのリトライ後に古い状態を使う。この種類はスタックトレースの最後だけ見ると、まったく別の場所が悪く見えます。ログの時刻、直前の操作、並列実行の有無、再実行で成功するかを伝えると、「常に再現するバグ」と「タイミング依存のバグ」を分けられます。
下の表が、種類ごとの「渡す材料」と「人間が検証すること」の早見表です。
| エラーの種類 | Claude Codeに渡す材料 | 期待する出力 | 人間が検証すること |
|---|---|---|---|
| TypeScript型エラー | tsc --noEmit --pretty false の全文、該当ファイル名 | 型の意味、壊れた契約、修正候補 | as any で逃げていないか |
| Node.jsスタックトレース | 先頭のError行、アプリ内フレーム、直前の入力 | 例外の発生点、再現条件 | 同じ入力で再現するか |
| Docker/Kubernetes | describe、前回ログ、イベント | OOM、環境変数、probe失敗の切り分け | kubectl で確認できるか |
| GitHub Actions | 失敗ジョブのログ、変更ファイル、ローカル実行結果 | 失敗段階、再現コマンド、次の修正 | CIだけの環境差分がないか |
Claude Codeが「この行を直せばよさそう」と返してきても、それが入力・環境・順序のどれなのか説明がなければ、まだ調査の途中です。僕はエラー対応の最初に必ず「これは入力・環境・順序のどれに見える?根拠行も示して」と聞きます。これだけで、原因に見える場所を場当たりで直す失敗が減りました。
ログを保存してから渡す(最後の行だけ貼らない)
最初にやることは、失敗した出力を消さないことです。ターミナルの最後の数行だけを貼ると、根本原因が消えます。PowerShellなら次の形で保存できます。
New-Item -ItemType Directory -Force tmp/error-cases | Out-Null
npm test 2>&1 | Tee-Object -FilePath tmp/error-cases/test.log
npx tsc --noEmit --pretty false 2>&1 | Tee-Object -FilePath tmp/error-cases/tsc.log
macOSやLinuxなら同じことをこう書きます。
mkdir -p tmp/error-cases
npm test 2>&1 | tee tmp/error-cases/test.log
npx tsc --noEmit --pretty false 2>&1 | tee tmp/error-cases/tsc.log
そのうえで、Claude Codeには「答え」ではなく「調査計画」を出してもらいます。
claude -p "
推測ではなく、再現できる修正がほしい。
次のファイルがあれば読んで:
- tmp/error-cases/test.log
- tmp/error-cases/tsc.log
返してほしいもの:
1. 一行の失敗サマリ
2. 有力な原因と確信度(confidence)
3. 最小の再現手順
4. 次に打つコマンド3つ
5. 試すべき最小・安全なコード変更
6. 修正後の検証コマンド
TypeScriptエラーを any や ts-ignore で隠さないこと。
"
ここでの肝は「確信度」を入れること。Claude Codeが断言できない場面では、「70%ならA、20%ならB」のように分けてもらいます。すると人間側が検証する順番を決めやすい。確信度100%と言い切ってくるときほど、僕は逆に証拠行を疑うようにしています。
スタックトレースは「最初のアプリ内フレーム」を読む
Node.jsのログは node_modules のフレームが大量に挟まって読みづらい。かといって削りすぎると原因まで消えます。だから全文は残したまま、Claude Codeに渡す要約版を別に作るのが安全です。
このスクリプトはそのまま動きます。標準入力でログを受け取り、依存パッケージ由来のフレームを3つだけ残して、アプリ側のフレームを浮かび上がらせます。
// scripts/minimize-stacktrace.mjs
import { readFileSync } from "node:fs";
// 標準入力からログ全文を読む
const input = readFileSync(0, "utf8");
const lines = input.split(/\r?\n/);
const kept = [];
let nodeModulesFrames = 0;
for (const line of lines) {
const isStackFrame = /^\s+at /.test(line);
const isDependencyFrame = line.includes("node_modules");
// 依存フレームは最初の3つだけ残し、あとは捨てる
if (!isStackFrame || !isDependencyFrame || nodeModulesFrames < 3) {
kept.push(line);
}
if (isStackFrame && isDependencyFrame) {
nodeModulesFrames += 1;
}
}
// エラー本体とアプリ側のフレームだけ拾う
const important = kept.filter((line) =>
/Error:|TypeError:|ReferenceError:|SyntaxError:|Caused by:|^\s+at |src\/|app\/|packages\//.test(line)
);
console.log(important.slice(0, 80).join("\n"));
実行はパイプでつなぐだけ。
node scripts/minimize-stacktrace.mjs < tmp/error-cases/test.log > tmp/error-cases/test.min.log
念押しですが、これは「診断」じゃありません。ただ読みやすくするだけのフィルタです。だからClaude Codeに依頼するときも、足りなければ全文を参照できる状態にしておきます。
claude -p "
まず tmp/error-cases/test.min.log を解析して。
要約版で足りなければ、推測せずに全文ログを要求して。
説明してほしいこと:
- 最初に役立つアプリ内フレームはどれか
- 再現にどんな入力や状態が必要か
- これは「非同期のタイミング」「null データ」「環境変数不足」「依存のバージョン違い」のどれに見えるか
- 修正前に失敗する最小のテスト
"
TypeScriptエラーは「契約違反」として読む
Type X is not assignable to type Y は、最初は暗号に見えます。でも多くは意味が一つで、「この関数が期待する形と、渡したデータの形が違う」だけ。専門用語でいう型契約、つまりコード同士の約束が破れている状態です。
Claude Codeには、型の説明だけでなく修正案の危険度まで出してもらいます。
claude -p "
このTypeScriptエラーを、呼び出し側と呼ばれ側の『契約違反』として説明して。
対象:
$(npx tsc --noEmit --pretty false 2>&1)
次の表で返して:
- エラー箇所
- 平易な日本語の説明
- 期待していたデータ形
- 実際に渡したデータ形
- 安全な修正
- 避けるべき危険な修正
他に手がない場合を除き、any・ts-ignore・strictモード削除は提案しないこと。
"
こうすると「型を黙らせる修正」と「バグを直す修正」を分けられます。User | null のエラーなら、as User で逃げるのではなく、ログイン前の状態をUIで扱う、APIの戻り値を検証する、テストデータに必須フィールドを足す、という方向に進めます。後者は地味ですが、本番で同じエラーが化けて出てくるのを防ぎます。
Docker/Kubernetesログは「次の確認コマンド」に変える
CrashLoopBackOff は結果であって原因ではありません。中身はメモリ不足、環境変数不足、DB接続失敗、Readiness probe失敗、起動コマンドの間違い、と全然違うものが混ざっています。まず材料を集めます。
kubectl get pod -n app
kubectl describe pod web-abc123 -n app > tmp/error-cases/pod.describe.txt
kubectl logs web-abc123 -n app --previous > tmp/error-cases/pod.previous.log
kubectl get events -n app --sort-by=.lastTimestamp > tmp/error-cases/events.log
依頼は、原因名だけで終わらせません。証拠行を必ず要求します。
claude -p "
このKubernetesのクラッシュをトリアージして。
ファイル:
- tmp/error-cases/pod.describe.txt
- tmp/error-cases/pod.previous.log
- tmp/error-cases/events.log
返してほしいもの:
1. 最有力カテゴリ(OOMKilled / 環境変数不足 / image pull / アプリ例外 / probe失敗 / 依存先の障害)
2. その根拠となるログの行
3. 残りの仮説を確認する kubectl コマンドを1つずつ
4. 暫定の回避策
5. 恒久対応
6. ロールバックの確認
証拠が足りないなら、どのコマンドが足りないか言って。
"
もっともらしい説明が返ってきても、ログのどの行に基づくのか言えないなら、それはまだ仮説です。証拠行を出させる癖をつけると、Claude Codeの「自信満々の的外れ」をかなり潰せます。
GitHub Actionsの失敗をローカル再現に落とす
CIの失敗は、ローカルでは通るのにGitHub Actionsだけ落ちることがあります。Node.jsのバージョン、OS、キャッシュ、環境変数、並列実行、タイムゾーンの違いが原因になります。まずログを取ります。
gh run list --limit 5
gh run view RUN_ID --log > tmp/error-cases/github-actions.log
次のプロンプトで「CIだけの問題」と「コードの問題」を分けます。
claude -p "
GitHub Actions の失敗をトリアージして。
tmp/error-cases/github-actions.log を解析して返して:
1. 失敗したジョブと失敗したステップ
2. 失敗した正確なコマンド
3. ローカルで再現するはずか
4. ローカル再現コマンド
5. CI固有の差分: Nodeバージョン、環境変数、キャッシュ、タイムゾーン、OS、権限
6. 試す最小のパッチ
7. ローカルとCI両方の検証プラン
ログが下流の症状しか示していないなら、根本原因を決め打ちしないこと。
"
この形にすると、CIログの末尾に並ぶ大量の依存エラーではなく、最初に壊れたステップに戻りやすくなります。CIのログは下に行くほど「巻き込まれて落ちた」ノイズが増えるので、上に戻るのが鉄則です。
コピペ用:構造化バグ報告テンプレート
Claude Codeに貼る前にこのテンプレートを埋めると、会話が一往復で済みます。チームなら .github/ISSUE_TEMPLATE/bug_report.md や docs/debug-template.md に置いても便利です。
# Bug report: short title
## Goal(やりたかったこと)
## Environment
- OS:
- Node version:
- Package manager:
- Branch:
- Commit:
## Exact command(実行した正確なコマンド)
```bash
paste the exact command here
```
## Expected result(期待した結果)
## Actual result(実際の結果)
## Logs
全文エラー、または保存したログのパスを貼る
## Minimal reproduction(まだ失敗する最小手順)
## What I already tried
- Attempt 1:
- Attempt 2:
## Verification plan(修正後に通るべきコマンド)
MDX記事の中にこのテンプレートを置くときは、コードブロックの中にさらにコードブロックを書くため、実ファイルではフェンスの閉じ忘れに注意してください(僕はこれで一度ビルドを壊しました)。
よくある質問
Q. Claude Codeにログ全文を貼れば、勝手に原因を当ててくれないの? A. 当たることもありますが、ログの外にある「実行コマンド」「期待結果」「環境」がないと一般論になりがちです。全文を貼るより、再現手順を添えるほうが効きます。
Q. ログが長すぎてコンテキストに入りません。
A. 全文はファイルに保存し、要約版を作って渡します。本文の minimize-stacktrace.mjs で node_modules のフレームを削ると、アプリ側だけ残って見やすくなります。
Q. 型エラーを as any で消すのはダメ?
A. 短期的には通りますが、テストや本番で別のエラーに化けます。型エラーは「契約違反の警告」。as で黙らせる前に、データ形を直すか検証を足すのが安全です。
Q. ログをそのまま貼って大丈夫? A. APIキー、Cookie、JWT、DB接続文字列は消してから渡してください。権限や共有設定は Claude Code settings で固めておくと事故が減ります。
Q. 修正後、どのコマンドで確認すればいい? A. まず落ちたコマンドをもう一度通します。それが緑になってから、関連テスト、lint、build、CIへと広げます。順番を逆にすると「直ったつもり」が生まれます。
実際に試した結果
このやり方に変えてから、僕のエラー対応で一番変わったのはTypeScriptの初動です。tsc --pretty false の保存、スタックトレースの最小化、CIログの「失敗ジョブ・失敗ステップ・再現コマンド」分解を固定したら、Claude Codeの提案をそのまま信じる代わりに、同じコマンドで検証しながら直せるようになりました。
正直、最初は「ログを保存する」「テンプレートを埋める」のがめんどくさくて何度もサボりました。でもサボった日に限って、Claude Codeの一般論に振り回されて30分溶かす。結局、最初の3分を惜しまないのが一番速い、というのが今の実感です。
調査の型をもっと固めたい人は Claude Codeエラー診断入門 と Claude Codeデバッグワークフロー、本番ログの見方は Claude Codeでログ監視基盤を作る が続きになります。チームで標準化したいなら、バグ報告テンプレートやCI triageプロンプトをまとめた Claude Code教材・テンプレート、導入を整理する 導入相談・研修 も覗いてみてください。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
まず無料PDFで基本を固め、繰り返し使う作業はGumroad教材へ、チーム導入や権限設計は導入相談へ進めます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Codeに1ファイルだけ直させる指示文のつくり方
「もっと良くして」で40行も変えられた失敗から学んだ、触る範囲・検証・戻し方をセットにしたClaude Code用の依頼文テンプレートを紹介します。
Claude Code の権限拒否から復旧する: 止まった理由を次の安全手順に変える
Claude Code のコマンドが拒否されたとき、焦って許可を広げずに、拒否理由、代替手順、証拠コマンド、再試行条件へ分解する方法。
Claude Codeにビルド→スモークテスト→自動修正を回させる足場の作り方
最小スモークテストの選び方、失敗ログを食わせて直させるループ、回数上限と確認ゲートで暴走を止める方法を、コピペで動くコード付きで紹介します。