TL;DR: Claude Code でよく起きる失敗は「存在しないファイルへの幻覚(hallucination)」「同じ修正を繰り返す無限ループ」「過去の指示が干渉するコンテキスト汚染」「指示範囲外の勝手変更(スコープクリープ)」「秘密情報のリーク」の5パターンです。各パターンに症状・原因・即使える対処法(コード/設定例付き)を整理しました。
📚 シリーズ: Claude Code シリーズ:環境設定から実践まで
はじめに
Claude Code(公式ドキュメント)は、コーディングタスクを自律的にこなせる強力な AI エディタです。しかし実務で使い始めると「なぜかうまく動かない」ケースが繰り返し発生します。
ほとんどの失敗は 5つのパターンのどれかに当てはまります。パターンを知っておけば、発生前に防ぎ、発生後も素早く対処できます。
本記事では AI とのペアプログラミング の経験を踏まえ、実際に遭遇した失敗を体系化しました。
パターン1: Hallucination(幻覚)— 存在しないファイル・関数の参照
症状
- 存在しないパスへの
importを繰り返し生成する - 「
src/utils/auth.tsを修正しました」と言うが、そのファイルは存在しない - エラーログを渡すと架空のメソッド名で修正しようとする
原因
Claude Code はコンテキスト窓(公式値では最大200K トークン)の範囲内でしか状況を把握できません。プロジェクト全体のファイル構造が共有されていないと、存在しないファイルを「あるはず」と推定します。特に大規模リポジトリで Read や Glob なしに指示するとハルシネーションが多発します(経験則)。
対処法
1. CLAUDE.md にファイル構造を明示する
## Project Structure
src/
api/ ← REST API エンドポイント
components/ ← React コンポーネント
hooks/ ← カスタムフック
utils/ ← ユーティリティ関数
types/ ← 型定義(index.ts で export)
## 重要ルール
- 新ファイル作成前に既存ファイルを確認すること
- src/utils/ 配下は必ず types/index.ts に型をエクスポートすること
2. タスク開始前に探索を義務付ける
まず Glob ツールで src/ 配下のファイル一覧を取得してから作業を開始してください。
3. allowedTools を指定して操作範囲を絞る
claude --allowedTools "Read,Glob,Bash(grep *)" "auth.ts の認証ロジックを確認して"
探索フェーズを Read と Glob のみに絞ることで、存在確認なしの生成を抑制できます(経験則)。
詳細な CLAUDE.md の書き方は CLAUDE.md パターン集 を参照してください。
パターン2: 無限ループ — 同じ修正を繰り返す
症状
- テスト失敗 → 修正 → 同じテスト失敗 → 同じ修正... のサイクルが止まらない
MAX_RETRY exceededエラーで強制終了- 「修正しました」と報告するが実際には同じコードになっている
原因
Claude Code のデフォルト動作は「エラーがあれば修正を試みる」です。エラーメッセージが曖昧だったり、前提条件(環境変数・DB接続など)が満たされていない場合、修正の試みが本質的な原因に届かずループします。
対処法
1. 指示に明示的な停止条件を含める
テストが2回連続で失敗した場合は修正をやめ、
以下の情報をまとめて報告してください:
- 失敗しているテスト名
- エラーメッセージ全文
- 試みた修正の一覧
2. Hooks でループ検知・エスカレーションを実装する
Claude Code Hooks 実践 で詳しく解説していますが、PostToolUse フックで連続失敗を検知できます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/retry-guard.sh"
}
]
}
]
}
}
#!/bin/bash
# .claude/hooks/retry-guard.sh
RETRY_FILE="/tmp/claude-retry-count"
COUNT=$(cat "$RETRY_FILE" 2>/dev/null || echo 0)
COUNT=$((COUNT + 1))
echo "$COUNT" > "$RETRY_FILE"
if [ "$COUNT" -ge 3 ]; then
echo "ERROR: 3回連続でコマンド実行。人間による確認が必要です。" >&2
rm -f "$RETRY_FILE"
exit 2 # Claude の実行をブロック
fi
3. エラーの前提条件を先に確認させる
テストを実行する前に、以下を確認してください:
1. .env ファイルが存在するか(test:integration 向け)
2. DATABASE_URL が設定されているか
3. 依存パッケージがインストールされているか(pnpm install)
パターン3: コンテキスト汚染 — 過去の指示が干渉する
症状
- セッション前半で「TypeScript 厳格モードで書いて」と指示したのに、後半で
anyだらけのコードが出てくる - 別タスクのコード規約(
snake_case等)が混入する - 「以前のタスクをやり直して」と言っても前の状態に戻れない
原因
Claude Code のコンテキスト窓は有限です。会話が長くなると、初期の指示が窓の外に押し出されたり、後から追加された相反する指示に上書きされたりします(公式ドキュメント参照)。
対処法
1. /compact コマンドでコンテキストを整理する
/compact
会話履歴を要約してコンテキスト使用量を削減します。長時間セッションでは 30 分ごとに実行するのが目安です(経験則)。
2. CLAUDE.md に不変ルールを記述する
会話コンテキストではなく、ファイルとして永続化することで「窓から消える」問題を回避します。
## 絶対に変えないルール(Override 不可)
- 変数名は camelCase(snake_case 禁止)
- any 型は使用禁止。unknown を使うこと
- console.log は本番コードに残さない
- テストは `tests/` 配下に配置する(src/ 配下禁止)
3. セッション分割の基準を決める
| セッションを切るタイミング | 理由 |
|---|---|
| 1タスクが完了し、別の機能着手 | コンテキストの混在を防ぐ |
| 会話が 100 ターンを超えた | コンテキスト窓の圧迫 |
| エラーが 3 回以上解決しない | 汚染されたコンテキストのリセット |
AI 駆動開発のプロジェクト計画術 では、タスク分割の設計方法を詳しく解説しています。
パターン4: スコープクリープ — 指示範囲外の勝手変更
症状
Buttonコンポーネントの修正を依頼したのに、ModalやFormまで変更された- 「関連するファイルも改善しました」と言いながら大量のファイルが変更される
- リファクタリングが勝手に走り、意図しない差分が混入する
原因
Claude Code は「関連する問題を見つけると直したくなる」傾向があります(経験則)。指示が「〇〇を改善して」のように広く解釈できる場合に多発します。
対処法
1. 変更対象ファイルを明示する
src/components/Button.tsx のみを変更してください。
他のファイルには一切触れないこと。
2. PreToolUse フックで特定ファイルへの書き込みをガードする
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/scope-guard.sh"
}
]
}
]
}
}
#!/bin/bash
# .claude/hooks/scope-guard.sh
# stdin から tool_input を受け取る
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))")
# 保護対象ディレクトリへの書き込みをブロック
PROTECTED="src/core/ src/lib/"
for dir in $PROTECTED; do
if [[ "$FILE_PATH" == *"$dir"* ]]; then
echo "ERROR: $dir への書き込みは人間の承認が必要です" >&2
exit 2
fi
done
3. 差分レビューを必須にする指示を追加する
変更を加える前に、変更予定のファイル一覧を列挙してください。
私が承認してから実際の変更を行ってください。
パターン5: 秘密情報のリーク — .env・APIキーの意図しない公開
症状
.envファイルがコミットに含まれる- APIキーがログ出力やコードコメントに埋め込まれる
secrets/配下のファイルが変更・読み取りされる
原因
Claude Code は明示的に制限しない限り、リポジトリ内の全ファイルを Read できます。--dangerouslyDisableSandbox フラグや広すぎる allowedTools 設定も漏洩リスクを高めます(公式セキュリティ設定参照)。
対処法
1. .claude/settings.json で denyList を設定する
{
"permissions": {
"deny": [
"Read(.env*)",
"Read(secrets/*)",
"Write(.env*)",
"Write(secrets/*)",
"Bash(cat .env*)",
"Bash(echo *SECRET*)",
"Bash(echo *KEY*)"
]
}
}
2. PreToolUse フックで機密ファイルへのアクセスをブロックする
#!/bin/bash
# .claude/hooks/secret-guard.sh
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))" 2>/dev/null)
COMMAND=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command',''))" 2>/dev/null)
DENY_PATTERNS=(".env" "secrets/" "*.pem" "*.key" "id_rsa")
for pattern in "${DENY_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]] || [[ "$COMMAND" == *"$pattern"* ]]; then
echo "ERROR: 機密ファイルへのアクセスはブロックされています: $pattern" >&2
exit 2
fi
done
3. CLAUDE.md に明示的な禁止事項を記述する
## 編集禁止ファイル
- `.env*` — 環境変数ファイル
- `secrets/` — 秘密情報ディレクトリ
- `*.pem`, `*.key` — 証明書・秘密鍵
これらのファイルは読み取りも書き込みも行わないこと。
5パターン 対処法チートシート
| パターン | 即効対処 | 恒久対処 |
|---|---|---|
| Hallucination | 探索フェーズを義務付ける | CLAUDE.md にファイル構造を記述 |
| 無限ループ | 停止条件を指示に含める | Hooks でループ検知・ブロック |
| コンテキスト汚染 | /compact を実行 | CLAUDE.md に不変ルールを記述 |
| スコープクリープ | 変更対象ファイルを明示 | PreToolUse Hook でガード |
| 秘密情報リーク | denyList を設定 | secret-guard.sh を常時有効化 |
FAQ
Q1: Claude Code が同じエラーを直せないとき、どう対処する?
エラーメッセージをそのまま渡すのではなく、「何を期待していたか」「何が起きているか」「試したがダメだったアプローチ」の3点を整理して渡してください。また、無限ループのパターン2で紹介した停止条件を事前に設定しておくと、ループ前に人間にエスカレーションされます。
Q2: セッションをリセットするタイミングは?
以下のサインがあったらリセットを検討してください:
- エラーが 3 回以上同じ箇所で繰り返される
- 会話が 100 ターン超
- 別タスクの指示が混入している気がする
--dangerouslyDisableSandboxを使っていた
Q3: Hallucination を完全に防ぐ方法はある?
完全な防止は困難です(経験則)。ただし「探索フェーズの義務付け」「CLAUDE.md によるファイル構造の明示」「allowedTools による操作範囲の限定」を組み合わせることで、発生頻度を大幅に下げられます。
Q4: 長時間タスクでコンテキストが壊れてきたら?
/compact コマンドを実行し、重要な前提条件(使用ライブラリ・コーディングルール・今回のタスク目標)を改めて指示として渡してください。CLAUDE.md に記述されたルールは /compact 後も参照されます(公式ドキュメント)。
Q5: コンテキスト汚染と Hallucination の違いは?
Hallucination は「存在しないものを存在すると誤認する」現象で、主にコンテキスト不足が原因です。コンテキスト汚染は「過去の指示が現在の判断に干渉する」現象で、コンテキストが多すぎることが原因です。前者はコンテキストの追加、後者はコンテキストの整理(/compact)で対処します。
👉 シリーズ全体像: Claude Code 環境セットアップガイド
まとめ
Claude Code の失敗の多くは、コンテキストの「量」と「質」のコントロールで防げます。
- 少なすぎる → Hallucination(CLAUDE.md で補充)
- 多すぎる・汚染 → ループ・スコープクリープ(
/compact・Hooks でガード) - 範囲設定が甘い → 秘密情報リーク(denyList・PreToolUse で制限)
Claude Code Hooks 実践 で各フックの実装方法を、AI 駆動開発のプロジェクト計画術 でタスク設計の方法を詳しく解説しています。失敗パターンを知ったうえで、適切な設計を組み合わせてください。
References
- Claude Code 公式ドキュメント(概要) — Anthropic 公式
- Claude Code Hooks 公式仕様 — Anthropic 公式
- Claude Code メモリ管理 — Anthropic 公式
- Claude Code 設定(セキュリティ含む) — Anthropic 公式
- プロンプトエンジニアリング概要 — Anthropic 公式
