バグに遭遇した時の動き方: 観察→再現→切り分け→記録→報告のランブック
不具合に当たったとき、何から手をつけるか。観察・再現・切り分け・記録・報告の順に動くランブックを、Claude Codeに渡せる形で具体例とコード付きで紹介。
金曜の夕方、「ログインできない」とだけ書かれた一行がSlackに流れてきました。
僕は反射的にコードを開いて、認証まわりを上から眺め始めました。30分後、当たりは出ません。落ち着いて聞き直したら、「特定のスマホだけ」「しかも昨日の夜から」。最初の一行に振り回されて、見当違いの場所を掘っていたわけです。
バグ対応で時間を溶かす原因は、たいてい腕の問題じゃありません。動く順番が決まっていないことです。火事の現場でいきなり水をまく前に、どこが燃えているか見るのと同じで、不具合にも「先に観察、次に再現、それから切り分け」という型がある。
この記事はその型——僕が毎回たどる**ランブック(動き方の手順書)**を、そのままClaude Codeに渡せる形でまとめたものです。バグ報告に何を書くかという「記入テンプレ」の話ではなく、報告にたどり着くまでの「足の動かし方」を順番に書きます。記入欄の話は姉妹記事 Claude Codeバグ報告テンプレート に分けました。
この記事の要点
- バグ対応は 観察 → 再現 → 切り分け → 記録 → 報告 の5ステップで動く。順番を飛ばすと迷子になる。
- 最初にやるのは修正じゃなく 再現。再現できないバグは直したかどうかも確かめられない。
- 切り分けの主役は 二分探索。怪しい範囲を半分ずつ削る。
git bisectはその自動版。 - Claude Codeには「直して」ではなく 観察した事実とやってほしいステップ を渡す。推測と事実を分けるのがコツ。
- 記録(再現手順・確認コマンド・残るリスク)を残すと、次のセッションで同じ説明を繰り返さずに済む。
なぜ「順番」がそんなに効くのか
腕のいい人とそうでない人の差は、ひらめきの量じゃありません。手戻りの少なさです。
順番が決まっていないと、人は目についた場所から触り始めます。さっきの僕のように、報告の一行目に引っぱられて認証コードを読み出す。でも実際の原因が「特定機種のCookie設定」だったら、その30分はまるごと無駄になります。
ランブックがあると、毎回ゼロから考えなくて済みます。観察が終わるまで修正に進まない、再現できるまで犯人探しをしない——このガードレールがあるだけで、深追いと空回りが減る。チェックリストを使う外科医や、離陸前に指差し確認するパイロットと同じ発想です。退屈に見えて、いちばん事故りにくい。
Claude Codeを使うと、この効果がさらに大きくなります。AIは「最後の一行のエラー」だけ見て、それっぽい修正を即座に出してきます。速いんですが、観察と再現を飛ばした修正は、別の形でバグを戻しがちです。だから人間側がランブックの順番を握って、AIには各ステップの作業を頼む。主導権はこっちが持つ、という分担にします。
ステップ1: 観察 — 事実と推測を分ける
最初にやるのは、コードを読むことでも直すことでもありません。何が起きているかを言葉にすることです。
ここでいちばん大事なのが、事実と推測を分けること。「ログインできない」は報告者の体験で、まだ事実じゃありません。事実はもっと具体的です。
| 集めるもの | 具体例 | なぜ要るか |
|---|---|---|
| 症状(1文) | 「Safariでログイン後、ログイン画面に戻される」 | 全員が同じバグを見ているか揃える |
| 発生条件 | 「iPhoneのSafariだけ」「昨夜のデプロイ後から」 | 再現と切り分けの当たりになる |
| 証拠 | エラーログ、スクショ、失敗したコマンド | 後で「直った」を測る基準になる |
| 期待した挙動 | 「ログイン後はダッシュボードに行くはず」 | 何をもって正常とするか決める |
「たぶんキャッシュのせい」みたいな推測は、出てきたら別の場所にメモします。捨てる必要はありません。仮説は切り分けの入り口として役に立つからです。ただし事実の欄に書かない。ここを混ぜると、推測がいつのまにか「直すべき要件」に化けて、見当違いの修正に進みます。さっきの僕がやったのが、まさにこれでした。
ステップ2: 再現 — 直す前に「呼び出せる」状態にする
観察で揃った条件をもとに、自分の手元でバグを起こします。再現はデバッグの土台です。再現できないバグは、直したかどうかも確認できません。
再現できたら、その手順を箇条書きで固定します。
- 環境を合わせる(ブラウザ、OS、ログイン状態、データ)
- 操作を順番に書く(「トップを開く→ログイン→3秒待つ」)
- 結果を書く(「ログイン画面に戻る」)
- できれば自動化する(失敗するテストを1本書く)
理想は4番です。バグを再現する失敗テストを1本書けると、対応のゴールが「このテストを緑にする」と一言で決まります。Claude Codeにもこのテストを渡せば、何が直ればいいのかを推測させずに済みます。
逆に「たまにしか出ない」バグは、ここで粘ります。発生したときの時刻・入力・ログを集めて、共通点を探す。再現条件が1つに絞れるまでは、原因探しに進まないほうが結局早いです。
ステップ3: 切り分け — 怪しい範囲を半分ずつ削る
ここがランブックの心臓部です。やることは1つ、二分探索。怪しい範囲を半分に割って、どちら側にバグがあるかを確かめ、また半分にする。これを繰り返すと、何百個の変更からでも数回で犯人にたどり着きます。
切り分けの軸はいくつかあります。
- 時間で割る: いつから壊れた? 動いていた時点と壊れた時点のコミットの間を二分探索する。
- 場所で割る: フロント? サーバー? DB? ネットワーク? どこまでが正常か確かめる。
- 入力で割る: どの入力で出て、どの入力で出ない? 違いがヒントになる。
- 環境で割る: 本番だけ? 手元でも? ステージングは? 差分が原因に直結する。
「いつから壊れたか」がわかっているなら、git bisect が二分探索を自動でやってくれます。動いていたコミットと壊れたコミットを教えると、Gitが中間を順番に出してきて、各地点で「good / bad」を答えるだけで犯人コミットを特定できます。この具体的なやり方は Claude Codeでバグを潰す手順 に分けて書きました。
切り分けで一番やってはいけないのが、ログを見ずに原因を決めつけること。「たぶんキャッシュ」で本番のキャッシュを消して回る、みたいな対応は、運がよければ直り、悪ければ別の何かを壊します。半分に割って、観察して、また割る。地味ですが、これが最短です。
ステップ4: 記録 — 未来の自分への引き継ぎ
犯人が見えたら、すぐ直したくなります。でもその前に、ここまでを短くメモします。記録は未来の自分(と同僚、と次のClaude Codeセッション)への引き継ぎです。
引き継ぎメモに入れるのは4つだけ。
- 再現手順: どうやってバグを起こすか
- 原因: どこの何が悪かったか(仮説なら仮説と明記)
- 確認コマンド: 何が緑になれば直ったと言えるか
- 残るリスク: 触ると危ない場所、未確認のケース
これがあると、対応が途中で中断しても再開できます。Claude Codeに続きを頼むときも、この4行を渡すだけで文脈が伝わる。逆にこれを残さないと、翌日の自分が「あれ、どこまでやったっけ」と振り出しに戻ります。僕はこれで何度も同じ調査を二度やりました。
ステップ5: 報告 — Claude Codeに「事実とステップ」で渡す
最後が報告です。人への報告でも、Claude Codeへの依頼でも、渡すものは同じ。観察した事実と、やってほしいステップです。
Claude Codeに渡すとき、避けたいのは「ログインのバグ直して」の一言。これだと範囲・証拠・確認方法・触ってほしくない場所を、全部AIが推測します。そうではなく、こう渡します。
- 触ってはいけない領域を先に名前で指定する(認証、課金、本番設定、マイグレーションなど)
- いきなり修正させず、まず診断を頼む
- 承認する変更を1つに絞る
- 確認コマンドを先に決めておく
収益・権限・本番デプロイが絡むときは、必ず停止点を置きます。自分で直していい範囲なのか、チームで設計を相談したほうがいい範囲なのか、ここで一度立ち止まる。「直せること」と「直していいこと」は別だからです。
コピペで動く: ランブックの抜け漏れチェッカー
報告に進む前に、ランブックの各ステップが埋まっているかを機械でチェックすると安心です。下のスクリプトは、観察・再現・切り分け・記録の材料が揃っているかを確認し、足りない項目を教えてくれます。Node.jsがあればそのまま動きます。
// runbook-check.mjs — バグ対応の抜け漏れを公開前に見える化する門番
// 使い方: node runbook-check.mjs
// 今回の対応状況をここに書く(埋まっていない項目は空のままにする)
const report = {
symptom: "Safariでログイン後、ログイン画面に戻される", // ステップ1: 観察(1文)
facts: ["iPhone Safariのみ", "2026-06-06のデプロイ後から"], // 事実(推測は入れない)
reproSteps: ["トップを開く", "ログイン", "3秒待つ"], // ステップ2: 再現手順
failingTest: "auth.spec.ts: redirect after login", // 再現を固定する失敗テスト
isolation: "git bisect で 2026-06-06 の cookie 設定変更に特定", // ステップ3: 切り分け結果
protectedFiles: ["auth", "billing", "production config"], // 触ってはいけない領域
proofCommand: "npm test -- auth.spec.ts", // 確認コマンド
handoff: "原因=SameSite設定 / リスク=他ブラウザ未検証", // ステップ4: 引き継ぎメモ
};
// 各ステップに必要な材料がそろっているか
const required = {
"観察(症状)": report.symptom,
"観察(事実)": report.facts,
"再現(手順)": report.reproSteps,
"切り分け": report.isolation,
"保護領域": report.protectedFiles,
"確認コマンド": report.proofCommand,
"引き継ぎ": report.handoff,
};
const missing = Object.entries(required).filter(([, value]) => {
return Array.isArray(value) ? value.length === 0 : !value;
});
if (missing.length === 0) {
console.log("OK: ランブックの各ステップが埋まっています。報告に進めます。");
} else {
console.log("未完了のステップがあります:");
for (const [name] of missing) console.log(` - ${name}`);
console.log("ここを埋めるまで、Claude Codeに広い権限を渡さないでください。");
}
実行するとこうなります。
node runbook-check.mjs
# => OK: ランブックの各ステップが埋まっています。報告に進めます。
このチェッカーは人間の判断を置き換えるものではありません。タスクが広がる前に、証拠不足を見える化するガードレールです。failingTest をわざと空にして実行すると、再現が固定できていないと教えてくれます。
3つの場面で、ランブックを当てはめる
実際の不具合に、5ステップをそのまま当てはめてみます。
1. ログイン後にログイン画面へ戻される
観察で「Safariだけ・デプロイ後から」と条件を絞る。再現は失敗テストを1本書いて固定。切り分けは git bisect でCookie設定の変更コミットに特定。記録に「原因=SameSite設定、未検証=他ブラウザ」と残す。報告では「認証と課金は触らず、Cookie設定だけ診断して」とClaude Codeに渡す。確認は認証テストが通り、課金ファイルが変わっていないこと。
2. 価格CTAのクリックが計測されない PVは伸びるのにGumroadクリックが見えない。観察では「クリック自体は起きているか」をまず分離する。切り分けで「リンクは正しい/イベント発火が抜けている」のどちらかに割る。再設計ではなくイベント配線だけに範囲を絞って依頼。確認はanalyticsイベントが出て、リンク先も正しいこと。深追いしてLP全体を作り直させないのがコツです。
3. 特定言語のMDX記事だけ表示が崩れる ある言語だけコードブロックが本文として出てしまう。観察で「どのslug・どの言語・どの行」かを特定。切り分けはcode fenceの開始/終了が揃っているかを半分ずつ確認。記録に崩れたslugと行番号を残す。報告では該当slugとfenceの行を添えて渡す。確認は公開URLのh1が正しく、ビルドが通ること。
僕がやらかした失敗3つ
正直に書きます。ランブックを使う前、僕の不具合対応は事故だらけでした。
ひとつ目は、報告の一行目に飛びついたこと。冒頭の「ログインできない」で認証コードを30分掘った件です。観察を飛ばすと、だいたい間違った場所から始めます。今は何があっても、まず症状と発生条件を書き出してからコードを開きます。
ふたつ目は、再現せずに直そうとしたこと。「たぶんこれだろう」で修正を入れて、本番で確認したら直っていない。当然です、再現できていないので直ったかどうかも測れない。失敗テストを先に1本書く癖をつけてから、この空振りが消えました。
みっつ目は、記録を残さなかったこと。夜に切り分けまで終えて、翌朝には「どこまでやったっけ」と振り出し。同じ git bisect を二度やったこともあります。引き継ぎメモを4行残すだけで、再開のコストがほぼゼロになりました。
よくある質問
Q. 再現できないバグはどうすればいい? A. 原因探しに進まず、観察に戻ります。発生したときの時刻・入力・環境・ログを集めて共通点を探す。再現条件が1つに絞れるまで粘るのが、結局いちばん速い。どうしても出ないなら、ログを増やして「次に出たら確実に捕まえる」準備をして待ちます。
Q. 切り分けって、結局どこから割ればいい?
A. 一番情報がある軸からです。「いつから壊れたか」がわかるなら時間(git bisect)、「本番だけ」なら環境、「特定の入力だけ」なら入力で割ります。迷ったら「正常と異常の境界はどこか」を1つ確かめる。それが次に割る場所を教えてくれます。
Q. Claude Codeに最初から全部任せたら早いのでは? A. 観察と再現が済んでいれば、かなり任せられます。でも「直して」の一言だと、AIは範囲も証拠も確認方法も推測します。事実と保護領域と確認コマンドを渡すほど、暴走が減って結果も速くなります。主導権は人間が握り、各ステップの作業をAIに頼む分担がちょうどいい。
Q. バグ報告に何を書けばいいか、欄がわからない A. 記入欄の型は Claude Codeバグ報告テンプレート にまとめました。この記事の「観察」で集めた事実を、そのままテンプレの欄に流し込むと、再現できる報告になります。
Q. 小さなバグでも毎回この5ステップを回すの? A. 慣れると数秒で頭の中を通過します。明らかな一行ミスならステップ3で即終わる。大事なのは順番を飛ばさないことで、各ステップに長くかける必要はありません。重いのは「再現できない」「原因が読めない」ときだけで、そこでこそランブックが効きます。
実際に試した結果
冒頭の「ログインできない」事件以来、僕は不具合に当たったとき「どこが悪いんだ」と頭を抱えるのをやめました。代わりに、いま自分はどのステップにいるかを確認します。
観察が済んでいないのにコードを開いていたら、戻る。再現できていないのに修正案を考えていたら、止まる。これだけで深追いがほぼ消えました。git bisect で時間軸を割る癖をつけてから、「いつから壊れた」系のバグは数分で犯人が出るようになった。そして引き継ぎメモを4行残すようにしたら、中断しても再開がただの続きになりました。
腕を上げようと焦るより、転んでも迷子にならない順番を先に決める。遠回りに見えて、これがいちばん速い、というのが今の実感です。次の不具合に当たったら、まず「観察→再現→切り分け→記録→報告」のどこにいるか、声に出して確かめてみてください。
もっと体系的に学びたい方へ。日々の操作と安全な依頼の型をまとめた 無料のClaude Codeチートシート や、ランブックを含む 教材一覧 もどうぞ。Claude Codeの公式ドキュメントは https://code.claude.com/docs/en/overview にあります。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
まず無料PDFで基本を固め、繰り返し使う作業はGumroad教材へ、チーム導入や権限設計は導入相談へ進めます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
制作会社がClaude Codeに触らせる前に決める権限チェックリスト
クライアントサイトを壊さずにAI編集を使うための、制作会社向け権限と確認の型です。
SaaSサポートのバグ報告をClaude Codeで再現手順に変える実務フロー
問い合わせ文をそのまま開発へ投げず、再現手順、証拠、次の一手に整えるサポート向け手順です。
Obsidianの古いメモをClaude Codeの指示書に変える10分ルーチン
Obsidianに溜めたメモが毎回ゴミになる人へ。事実・決定・未確認に仕分けして、Claude Codeがそのまま動ける指示書に変える朝の10分の型を紹介します。