error-recovery について
Error Recovery Protocolは、タスク失敗の診断と解決をエージェントに案内するスキルです。エラーの分類、既存の失敗記録や複数の情報源の参照、修正の検証、エスカレーションの手順を定めています。
主な機能
- 01エラーを6種類に分類
- 02既存の失敗記録を確認
- 03複数の情報源を一度に参照する復旧方針
- 04修正を検証して結果を記録
- 05再試行後のエスカレーションを規定
活用シーン
- 01ビルドやテスト失敗の診断
- 02ツールや実行時エラーからの復旧
- 03権限や認証情報の問題のエスカレーション
MCP 対応
precisionツールまたはMCPツールのエラーに関する案内を含みますが、MCPサーバーやMCPクライアント向け機能の説明はありません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mgd34msu/ goodvibes-plugin --skill error-recoveryインストール後、Claude Code で/error-recoveryを入力して読み込まれたか確認します。
同梱ファイルreferences/common-errors.mdscripts/validate-error-recovery.sh
詳細
リソース
scripts/
validate-error-recovery.sh
references/
common-errors.md
エラー復旧プロトコル
タスクが失敗した場合、エージェントは効率性と徹底性のバランスを取った体系的な復旧プロセスに従う必要があります。このスキルでは、エラーの分類方法、組織内のナレッジの活用方法、複数の情報源を用いた復旧戦略の適用方法、エスカレーションのタイミングについて定義します。
即時対応
タスクの実行中にエラーが発生した場合:
-
むやみに再試行しないでください。エラーメッセージ、スタックトレース、診断出力をすべて確認します。
-
エラーを次の6種類のいずれかに分類します:
- TOOL_FAILURE -- 精密ツールまたは MCP ツールがエラーを返した
- BUILD_ERROR -- ビルド/コンパイルコマンドに失敗した(npm、tsc、vite など)
- TEST_FAILURE -- テストスイートに失敗した(vitest、jest など)
- TYPE_ERROR -- TypeScript の型チェックに失敗した
- RUNTIME_ERROR -- 実行中にコードがクラッシュした
- EXTERNAL_ERROR -- サードパーティのサービスまたは API の障害
-
precision_read を使って、
.goodvibes/memory/failures.jsonに該当するキーワードがあるか確認します:- エラーメッセージからキーワードを検索します
- 一致するエラーが見つかった場合、記録されている
resolutionを適用します - 解決策が機能しない場合は、その旨を記録して復旧フェーズに進みます
- 見つからない場合は、そのまま復旧フェーズに進みます
エラーカテゴリ:詳細ガイダンス
TOOL_FAILURE
一般的な原因:
- ファイルパスが誤っている(絶対パスと相対パスの違い、タイプミス、ファイルが存在しない)
- ツールパラメーターの構文が不正(不正な JSON、誤った正規表現)
- サンドボックスが外部パスをブロックしている
- 必須パラメーターが指定されていない
- ツールの使い方が誤っている(抽出モードや出力形式が違う)
復旧手順:
- ツールのスキーマとパラメーターの説明を再確認します
- precision_glob を使ってファイル/パスが存在するか確認します
- precision_config get でサンドボックスの設定を確認します(
sandbox.enabledを確認) - 精密ツールでは、適切な抽出/出力モードを使用しているか確認します
- まず最小限のパラメーターで操作を試し、その後、複雑さを加えていきます
- 精密ツールが繰り返し失敗する場合、ユーザーの誤りか実際のツールの不具合かを確認します:
- ユーザーの誤り:パラメーターが誤っている、パスが不正、ツールの動作を誤解している
- ツールの不具合:正しいパラメーターを指定しているのに、ツールがクラッシュする、または誤った結果を返す
- ユーザーの誤りの場合は修正し、精密ツールで再試行します
- ツールの不具合の場合は、その操作に限ってネイティブツールへのフォールバックを使用し、その後は精密ツールに戻ります
メモリに記録されている一般的なパターン:
- 形式/モードの不一致:MCP スキーマでは
output.formatが送られますが、ハンドラーはoutput.modeを読み取ります。必ず??を使って両方を確認してください。 - Ripgrep のグロブに関する失敗:
src/**/*.tsのようなパターンは、ripgrep では何も出力せずに失敗します。正規表現でリテラルのプレフィックスを検出し、fast-glob を強制的に使用してください。 - パスの正規化:Ripgrep は絶対パスまたは相対パスを返します。必ず
path.resolve()の前にpath.isAbsolute()を使用してください。 - サンドボックスのオプトイン:
sandbox === true || sandbox === 'true'の場合にのみ有効にしてください。=== falseのチェックは絶対に使用しないでください。
BUILD_ERROR
一般的な原因:
- 依存関係が不足している(インストールされていない、バージョンが誤っている)
- 編集時に検出されなかった型エラー
- インポートエラー(パスが誤っている、循環依存)
- 設定エラー(tsconfig、vite.config など)
- 環境変数が不足している
復旧手順:
- ビルド出力をすべて確認します(stderr を取得するには、precision_exec で expect.exit_code を使用します)
- 一連のエラーのうち最初のエラーを特定します(後続のエラーは連鎖的に発生していることがよくあります)
- 依存関係が不足している場合:package.json を確認し、
npm installを実行します - 型エラーの場合:以下の TYPE_ERROR のセクションを参照します
- インポートエラーの場合:ファイルの存在を確認し、インポートパスを確認して、循環依存を探します
- 設定エラーの場合:コードベース内の正常に動作する例と比較します
- 使用しているフレームワーク/ビルドツールの公式ドキュメントを検索します
TEST_FAILURE
一般的な原因:
- テストのアサーションが誤っている(期待値が変更された)
- モックまたはスタブが不足している
- API 契約が変更された(関数シグネチャ、戻り値の型)
- テスト環境が正しく設定されていない
- 非同期処理のタイミングに関する問題
復旧手順:
- テスト失敗の出力を読みます(アサーションエラー、期待値と実際の値)
- 失敗したテストファイルと具体的なテストケースを特定します
- テストファイルを読み、何をテストしているのかを把握します
- 実装を読み、テストの期待値と一致しているかを確認します
- テストと実装のどちらが誤っているかを判断します:
- 実装が意図的に変更された場合 → テストを更新します
- 実装に問題がある場合 → 実装を修正します
- 非同期処理の問題については、
awaitの不足、done()の不適切な使用、または競合状態がないか確認します - 環境の問題については、テスト設定ファイル(vitest.config、jest.setup.js)を確認します
TYPE_ERROR
一般的な原因:
- 安全でないメンバーアクセス(
objが null/undefined の可能性があるのにobj.propにアクセスする) - 代入時の型の不一致(
stringをnumberに代入する) - 関数呼び出しのシグネチャが誤っている(パラメーターが不足している、型が誤っている)
- 型システムをすり抜ける、安全でない
anyの使用 - ジェネリックの制約違反
復旧手順:
- TypeScript のエラーメッセージを読みます(ファイル、行、具体的な型の問題が記載されています)
- 利用可能な場合は、analysis-engine ツールの
explain_type_errorを使用します - メンバーアクセスの場合:オプショナルチェーン(
?.)または null チェックを追加します - 代入の場合:元の箇所で型を修正するか、適切な型アサーションを使います
- 関数呼び出しの場合:関数のシグネチャを確認し、正しい引数を渡します
anyの使用の場合:anyを適切な型に置き換えます- ジェネリックの場合:型パラメーターが制約を満たしていることを確認します
一般的なパターン:
- 型ガードを追加します:
if (obj && 'prop' in obj) - オプショナルチェーンを使用します:
obj?.prop?.nestedProp - 判別可能なユニオンで型を絞り込みます
- カスタムガードには型述語を使用します
RUNTIME_ERROR
一般的な原因:
- null/undefined へのアクセス(null のプロパティへのアクセス、undefined を関数として呼び出す)
- 未処理の Promise の拒否
- 捕捉されていない例外
- 環境変数の不足
- ネットワーク障害(fetch、API 呼び出し)
- ファイルシステムエラー(ENOENT、EACCES)
復旧手順:
- スタックトレースを読み、失敗した正確な行を特定します
- 根本原因(null へのアクセス、環境変数の不足、ネットワークなど)を特定します
- null/undefined の場合:実行時チェックを追加するか、オプショナルチェーンを使用します
- Promise の場合:
.catch()ハンドラーを追加するか、awaitをtry/catchで囲みます - 環境変数の場合:
.envファイルを確認し、読み込まれていることを検証します - ネットワークの場合:リトライロジックを追加し、認証情報を確認して、URL を検証します
- ファイルシステムの場合:パスが存在することを確認し、権限を確認します
一般的なパターン:
- React コンポーネントにエラーバウンダリーを追加します
- すべての
await式をtry/catchで囲みます - 起動時に環境変数を検証します
- 防御的チェックを追加します:
if (!value) throw new Error('...')
EXTERNAL_ERROR
一般的な原因:
- 認証の有効期限切れまたは無効(401)
- レート制限超過(429)
- サービスの停止または到達不能(503、ECONNREFUSED)
- API リクエストが無効(400)
- クォータ超過
復旧手順:
- エラーのステータスコードまたはメッセージを確認します
- 認証エラー(401)の場合:
.goodvibes/secrets/内の認証情報を確認し、トークンの有効期限が切れていないか検証します - レート制限(429)の場合:指数バックオフを実装し、クォータを増やせるか確認します
- サービス停止(503)の場合:バックオフを使って再試行し、サービスのステータスページを確認します
- 不正なリクエスト(400)の場合:API ドキュメントを読み、リクエスト形式を検証します
- クォータの場合:使用状況ダッシュボードを確認し、上限の引き上げを依頼するか、リセットを待ちます
一般的なパターン:
- 指数バックオフ:1s、2s、4s、8s
- precision_fetch を使ってステータスエンドポイントからサービスの状態を確認します
- 複数の API キーを利用できる場合はローテーションします
- API 呼び出しを減らすため、レスポンスをキャッシュします
復旧戦略:一度にすべてのソースを確認
エラーを分類し、failures.json を確認したら、**一度にすべてのナレッジソースを同時に確認する(一つずつ順番に確認するのではなく)**戦略を使い、最適な解決策を適用します。
- 内部ナレッジ -- トレーニングデータ、コードベースのパターン(discover、precision_grep、precision_read)、GoodVibes のメモリ
- 公式ドキュメント -- 公式ドキュメント、API リファレンス、変更履歴、移行ガイド
- コミュニティのナレッジ -- Stack Overflow、GitHub Issues、フォーラム
- オープンインターネット -- エッジケースを幅広くウェブ検索
最適な解決策の適用
すべてのソースを確認したら、次の手順を実行します。
-
解決策を評価します。次の点を考慮してください。
- 新しさ(近いバージョン向けの解決策を優先)
- 信頼性(公式ドキュメント > コミュニティ > 無作為なブログ)
- 具体性(エラーと完全に一致する情報 > 一般的なガイダンス)
- プロジェクトとの適合性(使用しているスタックやパターンとの一致)
-
解決策を完全に適用します。
- 修正を中途半端に適用しないでください
- 関連する変更をすべて一度に行ってください
- 段階的な微調整ではなく、precision_edit を使って変更してください
-
修正を検証します。
- 失敗した操作を再実行します
- precision_exec で関連するテストを実行します
- 新たなエラーが発生していないか確認します
解決後
エラーの解決に成功したら、次の手順を実行します。
1. .goodvibes/memory/failures.json に記録する
precision_edit を使って、次の新しいエントリを追加します。
{
"id": "fail_YYYYMMDD_HHMMSS",
"date": "ISO-8601 timestamp",
"error": "Brief description of the error",
"context": "What was being attempted when error occurred",
"root_cause": "Why it happened (technical explanation)",
"resolution": "How it was fixed (specific steps taken)",
"prevention": "How to avoid this in the future",
"keywords": ["relevant", "search", "terms"]
}
例:
{
"id": "fail_20260215_143000",
"date": "2026-02-15T14:30:00Z",
"error": "precision_read returns 'file not found' for valid path",
"context": "Reading component file at src/components/Button.tsx",
"root_cause": "Path was relative, but precision tools require absolute paths. Sandbox was enabled, blocking CWD resolution.",
"resolution": "RESOLVED - Used absolute path with process.cwd() to create absolute path before calling precision_read.",
"prevention": "Always use absolute paths with precision tools. Use path.resolve() to convert relative to absolute.",
"keywords": ["precision_read", "path", "absolute", "relative", "sandbox", "file-not-found"]
}
2. .goodvibes/logs/errors.md に記録する
precision_edit を使って、次の Markdown エントリを追記します。
## [YYYY-MM-DD HH:MM] ERROR_CATEGORY: Brief Description
**Error**: Full error message
**Context**: What was being done
**Resolution**: How it was fixed
**Time to resolve**: X minutes
---
3. タスクを続行する
記録したら、元のタスクに戻ります。確認を待たないでください。
最大試行回数を超えた場合(3 回)
エラーを 3 回修正しようとしても失敗する場合:
1. 未解決の失敗を記録する
"resolution": "UNRESOLVED - <what was tried>" を指定して、failures.json に追加します。
{
"id": "fail_20260215_143500",
"date": "2026-02-15T14:35:00Z",
"error": "Vitest tests hang indefinitely on CI",
"context": "Running npm run test in CI pipeline",
"root_cause": "Unknown - tests pass locally but hang in CI environment",
"resolution": "UNRESOLVED - Tried: 1) Added --no-watch flag, 2) Increased timeout to 60s, 3) Disabled coverage collection. Tests still hang.",
"prevention": "Need deeper investigation into CI environment differences",
"keywords": ["vitest", "ci", "hang", "timeout", "unresolved"]
}
2. オーケストレーターに報告する
回答には構造化された形式を使います。
## Task Status: BLOCKED
### Error
[ERROR_CATEGORY] Brief description
### Attempts Made
1. **Attempt 1**: What was tried -> Result
2. **Attempt 2**: What was tried -> Result
3. **Attempt 3**: What was tried -> Result
### Root Cause Analysis
Best guess at why this is failing based on investigation.
### Suggested Next Steps
- Option 1: [Describe approach that requires different permissions/access]
- Option 2: [Describe alternative architecture/design decision]
- Option 3: [Describe manual intervention needed]
### Files Changed
- `path/to/file.ts` - [what was changed during troubleshooting]
3. タスクを完了としてマークしない
タスクは BLOCKED 状態のままにします。オーケストレーターが次の対応を判断します。
- ユーザーにエスカレーションする
- 別のアプローチを試す
- 異なる能力を持つ別のエージェントに割り当てる
- タスクを延期する
即時エスカレーション(復旧をスキップ)
特定の種類のエラーについては、復旧を試みず、すぐにオーケストレーターへエスカレーションします。
1. 権限エラー
EACCES: permission denied
EPERM: operation not permitted
理由:これらのエラーを解決するには、権限を付与するためにユーザーの介入が必要です。エージェントでは修正できません。
エスカレーション時の報告:「権限エラーが発生しました。ユーザーによる次の対応が必要です:[ファイルへのアクセス権を付与する/sudo で実行する/所有者を変更する]。」
2. 認証情報/シークレットの不足
Error: OPENAI_API_KEY is not defined
Error: Database connection failed: authentication error
401 Unauthorized
理由:エージェントはシークレットを作成または変更できません。認証情報を提供できるのはユーザーだけです。
エスカレーション時の報告:「認証情報が不足しています:[ENV_VAR_NAME またはサービス名]。ユーザーは .env またはシークレット管理を通じて提供する必要があります。」
3. アーキテクチャ上の曖昧さ
Context clues indicate multiple valid approaches:
- Use REST API vs GraphQL
- Use Prisma vs Drizzle
- Component composition pattern unclear
理由:これらはシステム全体に影響する設計上の決定です。エージェントが独断でアーキテクチャを決定するべきではありません。
エスカレーション時の報告:「アーキテクチャ上の決定が必要です:[選択肢を説明]。選択肢:[トレードオフを含めて 2~3 個の選択肢を列挙]。」
4. スコープ変更の発覚
Original task: "Add user profile page"
Discovered: Requires new database schema, auth changes, API endpoints
理由:タスクが当初の想定より大きくなっています。オーケストレーターによる再計画が必要です。
エスカレーション時の報告:「スコープの拡大が発覚しました。当初:[タスク]。必要:[新しい依存関係/変更]。推奨:[サブタスクに分割する/ユーザーの承認を得る]。」
概要
エラーが発生した場合:
- 直ちに分類します(TOOL_FAILURE、BUILD_ERROR など)。
- failures.json で既知のパターンを確認します。
- 複数の情報源を一度に使って復旧します(内部情報+ドキュメント+コミュニティ+ウェブ)。
- 最適な解決策を完全に適用します。
- 解決方法を failures.json と errors.md に記録します。
- タスクを続行します。
3 回試行した後:
- UNRESOLVED として記録します。
- 構造化された概要を添えてオーケストレーターに報告します。
- タスクを完了としてマークしないでください。
次の場合は直ちにエスカレーションします:
- 権限エラー
- 認証情報の不足
- アーキテクチャ上の曖昧さ
- スコープの変更
覚えておくこと:
- 精密ツールを標準とし、ネイティブツールはフォールバックとして使用します。
- ユーザーエラー ≠ ツールの失敗
- 復旧の試行は体系的に行い、手当たり次第に行わないでください。
- メモリーは組織の知識です。活用し、蓄積に貢献してください。