Tips & Tricks (更新: 2026/6/2)

Claude Codeエラー診断入門: ログから再現テストまでの実務手順

Claude Codeでエラー診断を再現、仮説、回帰テスト、検証まで進める実務手順。ログの読み方と失敗例も解説。

Claude Codeエラー診断入門: ログから再現テストまでの実務手順

エラー診断は「赤いログを見て勘で直す作業」ではありません。失敗した事実を、再現できる証拠に変える作業です。Claude Codeを使うと、この証拠集め、仮説作り、最小再現、テスト追加、修正、検証までを一つの流れにできます。

最初に押さえる言葉は3つだけです。ログは、コマンドやアプリが出した記録です。スタックトレースは、エラーに到達するまでに呼ばれた関数の道筋です。最小再現は、余計な画面や設定を削っても同じ失敗が起きる小さな例です。

Claude Codeに「直して」と丸投げするより、「どの証拠を見て、どの仮説を検証し、何で直ったと判断するか」を渡した方が、修正の質は上がります。この記事では、初心者でもそのまま使える形で、エラー診断の型をまとめます。

関連する基礎として、ビルド失敗を15分で分ける Claude Codeビルドエラー切り分けループ、ログ文言の読み方を整理した Claude Codeエラーメッセージ解読、報告の型を作る Claude Codeバグ報告テンプレート も合わせて読むと実務に落とし込みやすくなります。

エラー診断の全体像

flowchart LR
  A["失敗コマンドを保存"] --> B["最初の失敗行を探す"]
  B --> C["原因仮説を3つに絞る"]
  C --> D["最小再現を作る"]
  D --> E["回帰テストを追加"]
  E --> F["最小修正"]
  F --> G["同じコマンドで検証"]
  G --> H["引き継ぎメモを残す"]

この順番を守る理由は単純です。先に修正へ飛ぶと、たまたま通っただけなのか、本当に原因を消したのかが分かりません。特にClaude Codeは広い範囲を読めるので、指示が曖昧だと「ついでの整理」まで提案することがあります。診断の目的は、変更を増やすことではなく、失敗の原因を狭めることです。

まずは次の4点を揃えます。

見るもの目的Claude Codeに渡す例
失敗したコマンド再現手順を固定するnpm run buildnode --test
最初の失敗行ログ末尾のノイズを避けるTypeErrorERR_MODULE_NOT_FOUND
実行環境環境差分を切り分けるNode.js版、OS、CI名
期待値正しい挙動を決めるnullなら空配列、404なら再試行しない

JavaScriptの標準的なエラー名は MDNのJavaScript error reference が役に立ちます。Node.jsでは Node.js Errors docs に、error.message は変わる可能性があるため error.code を見た方が安定する、という考え方が示されています。PlaywrightのE2Eテストなら Debugging Tests | Playwright のInspector、Trace Viewer、VS Code連携を参照すると、画面操作の失敗をログだけで判断しなくて済みます。

Claude Codeに任せる7ステップ

実務では、次のプロンプトを1つの作業単位として使います。

claude -p "
次のエラーを診断してください。

1. 失敗したコマンドを確認する
2. 最初の失敗行と関係ないログを分ける
3. 原因仮説を最大3つ出す
4. 最小再現を作る
5. 回帰テストを追加する
6. 最小の修正だけを入れる
7. 同じコマンドで検証し、引き継ぎメモを書く

制約:
- 関係ないリファクタリングは禁止
- 既存の公開APIを変える場合は理由を書く
- 検証コマンドが失敗したら、修正済みと言わない
"

ここで大事なのは「最大3つ」です。仮説を10個並べると、結局どれも検証されません。たとえば Cannot read properties of undefined なら、APIレスポンスの形が違う、初期値が未設定、非同期読み込み前に描画している、の3つで十分です。

ユースケース1: Reactのundefinedエラー

典型例は、APIが null を返したのに users.map(...) を呼んで落ちるケースです。エラー文だけを見るとReactの問題に見えますが、実際にはデータの形の問題です。

// user-list.mjs
export function names(users) {
  if (!Array.isArray(users)) {
    return [];
  }

  return users.map((user) => user.name ?? "(no name)");
}
// user-list.test.mjs
import assert from "node:assert/strict";
import test from "node:test";
import { names } from "./user-list.mjs";

test("names returns an empty array when the API returns null", () => {
  assert.deepEqual(names(null), []);
});

test("names keeps valid user names", () => {
  assert.deepEqual(names([{ name: "Masa" }]), ["Masa"]);
});
node --test user-list.test.mjs

古い実装が return users.map(...) だけだった場合、このテストは落ちます。Claude Codeには「この失敗を再現するテストを先に追加し、通すための最小修正を入れてください」と頼みます。ガードを入れるだけで済むなら、状態管理やAPI層を大きく変える必要はありません。

ユースケース2: Node.jsのENOENTと依存関係エラー

ENOENT は、ファイルやディレクトリが見つからないときによく出ます。落とし穴は、ローカルでは存在する config/local.json が、CIやDockerイメージには入っていないケースです。

見る順番は、失敗コマンド、error.codeerror.path、DockerfileのCOPY.gitignore、CIのworking directoryです。Claude Codeには、次のように渡します。

claude -p "
Node.jsのENOENTを診断してください。
error.code、error.path、実行ディレクトリ、Dockerfile、CI設定を見てください。
ローカル専用ファイルに依存しない修正だけ提案してください。
"

ここで「ファイルを作って終わり」にすると、本番ではまた落ちます。設定ファイルが必須なら起動時に明確なメッセージを出す、任意ならデフォルト値に逃がす、CIで必要ならサンプル設定をコピーする、という判断まで必要です。

ユースケース3: PlaywrightのCIだけ失敗するテスト

Playwrightのタイムアウトは、アプリのバグ、テストの待ち方、CIの遅さ、認証切れ、ネットワーク差分が混ざります。スクリーンショット1枚だけで直そうとすると、待機時間を伸ばすだけの修正になりがちです。

まずはTrace Viewerを残します。

// playwright.config.ts
import { defineConfig } from "@playwright/test";

export default defineConfig({
  use: {
    screenshot: "only-on-failure",
    trace: "retain-on-failure",
    video: "retain-on-failure",
  },
});

Claude Codeには、失敗したspec、locator、期待した画面、traceの保存場所、CIの実行コマンドを渡します。指示は「timeoutを増やす前に、待つべきUI状態、APIレスポンス、認証状態を切り分けてください」にします。Playwrightの公式デバッグ手順と組み合わせると、ログだけでは見えないDOM状態も診断できます。

ユースケース4: TypeScriptの連鎖エラー

型エラーが20個出ると全部別の問題に見えます。しかし、最初の1つがAPI型の変更で、残りは連鎖しているだけのことがあります。

npx tsc --noEmit --pretty false 2>&1 | tee tsc.log
claude -p "
tsc.logを読んで、最初に直すべき型エラーを1つ選んでください。
派生エラーと根本原因を分けてください。
修正後はnpx tsc --noEmit --pretty falseで検証してください。
"

ポイントは、全部を同時に直させないことです。まず根本の型定義を直し、同じコマンドを再実行し、残ったエラーだけを見る。この小さなループが、余計な型アサーションを増やさないコツです。

ログとスタックトレースを分類する小さな道具

長いログを読む前に、代表的なパターンへ分類すると初動が速くなります。次のファイルはそのまま実行できます。

// triage-log.mjs
import fs from "node:fs";

const sample = `
TypeError: Cannot read properties of undefined (reading 'map')
    at ProductList (src/ProductList.tsx:42:18)
`;

const input = process.argv[2]
  ? fs.readFileSync(process.argv[2], "utf8")
  : sample;

const rules = [
  [/ERR_MODULE_NOT_FOUND|Cannot find module/i, "依存関係またはimportパス"],
  [/ENOENT/i, "ファイルパスまたは実行ディレクトリ"],
  [/TypeError:.*undefined|Cannot read properties/i, "データ形状または初期値"],
  [/Timeout.*expect|locator/i, "E2Eの待機条件または画面状態"],
  [/TS\d{4}/, "TypeScriptの型エラー"],
];

const matches = rules
  .filter(([pattern]) => pattern.test(input))
  .map(([, label]) => label);

console.log(matches.length ? matches.join("\n") : "分類不能: 最初の失敗行を確認");
node triage-log.mjs
node triage-log.mjs tsc.log

この道具は完璧な診断器ではありません。目的は、Claude Codeに渡す前に「依存関係なのか、データ形状なのか、E2Eの待機なのか」を粗く分けることです。

再現できるバグ報告テンプレート

Claude Codeに調査を頼む前に、バグ報告をこの形へ整えると、会話の往復が減ります。GitHubで運用するなら、公式の GitHub issue forms syntax を使って同じ項目をフォーム化できます。

## 概要
何が壊れているかを1文で書く。

## 失敗したコマンド
`npm run build`

## 期待した結果
ビルドが成功し、`dist/` が生成される。

## 実際の結果
`TypeError: Cannot read properties of undefined` で失敗する。

## 最初の失敗行
`src/components/ProductList.tsx:42:18`

## 再現手順
1. `npm ci`
2. `npm run build`

## 環境
- Node.js: 22.x
- OS: Windows 11 / GitHub Actions ubuntu-latest
- Branch: feature/product-list

## すでに試したこと
- lockfile再生成
- APIレスポンスのfixture確認

## 修正後に通す検証
- `node --test`
- `npm run build`

このテンプレートは、人間への報告にもClaude Codeへの入力にも使えます。大切なのは「困っています」ではなく、「この手順で同じ失敗が起きます」と言えることです。

よくある失敗と落とし穴

1つ目は、ログの最後だけを貼ることです。最後の行は「処理が止まった場所」であって、原因とは限りません。最初の失敗行と、その直前の数十行を残します。

2つ目は、エラー文の文字列だけで条件分岐することです。Node.jsではメッセージが変わる可能性があるため、可能なら error.codename を使います。

3つ目は、最小再現を作らないことです。巨大な画面のまま直すと、偶然別の状態で通っただけなのか判断できません。

4つ目は、テストなしで修正することです。回帰テストがない修正は、次のリファクタリングで同じバグを戻します。

5つ目は、Claude Codeに広すぎる権限を与えることです。「関連ファイルを全部きれいにして」ではなく、「この失敗を通すための最小変更」に絞ります。作業範囲の守り方は Claude Codeレビュー運用チェックリスト も参考になります。

引き継ぎメモまで書かせる

修正が通ったら、最後に短いメモを残します。これはレビュー担当者だけでなく、翌週の自分を助けます。

## 診断メモ
- 失敗: `npm run build`
- 原因: APIがnullを返すケースで`users.map`を呼んでいた
- 修正: `names()`で配列以外を空配列に正規化
- 回帰テスト: `node --test user-list.test.mjs`
- 検証: `npm run build`成功
- 未対応: API側でnullを返す仕様が正しいかは別issueで確認

Claude Codeへの最後の指示はこうです。

claude -p "
今回の診断メモをMarkdownで作成してください。
原因、変更点、追加した回帰テスト、検証コマンド、残リスクを
レビュー担当者が5分で読める長さにまとめてください。
"

相談・テンプレート導入

個人開発なら、この記事のコマンドとテンプレートをコピーするだけで十分です。チームで使うなら、ログに含めてよい情報、Claude Codeに渡してはいけない秘密情報、最小再現の保存場所、CIで必ず残すartifact、レビューで求める検証証拠を決める必要があります。

ClaudeCodeLabでは、実務向けの Claude Code教材・テンプレートClaude Code導入相談・研修 を用意しています。エラー診断を属人化させたくない場合は、バグ報告フォーム、CIトリアージプロンプト、回帰テストの書き方、引き継ぎメモの型までまとめて整備するのが近道です。

この記事で紹介した流れをMasaの保守作業で試した結果、最も効果があったのは「最初の失敗行」「最小再現」「同じコマンドでの再検証」を固定したことでした。Claude Codeの提案をそのまま信じるのではなく、証拠、仮説、テスト、検証を毎回残すことで、短い修正でもレビューしやすくなりました。

#claude-code #デバッグ #エラー診断 #不具合調査
無料

無料PDF: Claude Code はじめてのチートシート

まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。

スパムは送りません。登録情報は厳重に管理します。

Claude Codeを仕事で使える形にしませんか?

無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。

Masa

この記事を書いた人

Masa

Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。

PR

関連書籍・参考図書

この記事のテーマに関連する書籍を楽天ブックスで探せます。

※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。