error.json スキーマが MCP と A2A レスポンスエンベロープにどのようにマッピングされるかを定義します。
エラースキーマ自体、標準コード、リカバリー戦略についてはエラーハンドリングを参照。
層の分離
トランスポートエラーはプロトコルライブラリが処理します。アプリケーションエラーはビジネスロジックが処理します。混在させると、AdCP エラーを有用にする構造化リカバリーデータが失われる。
MCP バインディング
ツールレベルエラー
すべての AdCP エラーコードの標準パス。ツールが実行し、リクエストを理解して、構造化エラーを返します。 現在の実用的なパス: ほとんどの MCP ホスト(Claude Desktop、Cursor、Windsurf)はエラーレスポンスのcontent テキストを読み取り、structuredContent を LLM やプログラム的なコンシューマーに公開しません。structuredContent の採用が広まるまで、テキストフォールバックパスがほとんどのエラーが抽出される方法です。サーバーは両方のパスをサポートすべきだ:
content テキストは AdCP エラーをテキストベース抽出用の JSON 文字列として含みます。structuredContent.adcp_error はプログラム的クライアントが同じエラーをサポートする場合に含みます。人間が読めるテキストを含めるサーバーは2番目のコンテンツアイテムとして追加すべきで、簡潔に保つ(1文):
structuredContent 存在時の簡潔なテキスト。 structuredContent が完全なエラーを含む場合、人間が読めるテキストコンテンツアイテムは1つの簡潔な文(例: “Rate limited — retry in 5s.”)にすべきです。エラーの詳細はすでに structuredContent と JSON テキストフォールバックにある。散文でエラー全体を繰り返すと、特にリトライ中に蓄積する一時的なエラーの場合、LLM コンテキストトークンが無駄になります。
adcp_error キー: 名前空間化により structuredContent にも現れる可能性のある成功データ(例: products)との衝突を避ける。単一のキーにより検出が簡単になります。
structuredContent には MCP 2025-03-26 以降が必要です。古い MCP バージョンのサーバーは structuredContent を省略する — content[0].text の JSON 文字列で十分です。クライアントはテキストフォールバックパスを通じてこれを解析する(クライアント検出順序を参照)。
トランスポートレベルエラー
ツールディスパッチの前にインフラ(API ゲートウェイ、レートリミットミドルウェア)がリクエストを拒否した場合、ツールは実行されない。data に AdCP エラーを含む予約済み JSON-RPC エラーコードを使用します:
予約済み JSON-RPC コード
これらのコードは JSON-RPC サーバー定義範囲(
-32000 から -32099)にある。他のすべての AdCP エラーコードはツールレベルパスのみを使用します。
MCP サーバー SDK の注意: ツールハンドラー内から
McpError をスローすると JSON-RPC エラーレスポンスが生成される — SDK はそれを isError: true ツール結果に変換しない。つまり -32029 はミドルウェアからスローされても、ツールハンドラーからスローされても同じように機能します。しかしアプリケーション層エラー(ツールがリクエストを理解して構造化された失敗を返す場合)は、JSON-RPC エラーコードではなく上記の isError: true ツールレベルパスを使うべきです。-32029/-32028/-32027 はツールディスパッチ前にリクエストを拒否するインフラのために予約します。MCP サーバー実装
A2A バインディング
失敗したタスク
DataPart の AdCP エラーと人間/LLM 用の TextPart を含む status: "failed" を使用します:
.artifacts を使用します。
「ラッパーなし」ルールとの関係。 adcp_error キーは失敗したタスクの意図的な例外です。成功レスポンスの DataPart がタスク固有のデータ(例: products)を含むのとは異なり、失敗したタスクの DataPart はエラーのみを含みます。このキーは型の識別子として機能し、クライアントがステータスだけに頼ることなくエラーと成功ペイロードを区別できるようにします。
エラー MIME タイプ(オプション)
A2A エージェントはエラーDataPart の metadata.mimeType を設定してもよい:
adcp_error キーが権威あるシグナルです。
エンベロープ vs. ペイロードエラー
AdCP はエラーを 2 つの異なる場所で公開します。本ページはトランスポートエンベロープ(adcp_error)を扱います。ペイロードエラー配列(errors[])は Error Handling — Envelope vs. payload errors で扱います。
致命的なタスク失敗は両方の層を設定すべきです(SHOULD) — 正規の
protocol-envelope.json の例と、規範的な SHOULD については error-handling.mdx リファレンスを参照してください。
クライアント検出順序
クライアントはこの順序で AdCP エラーを確認しなければなりません:structuredContent.adcp_error(isError: true付き)— MCP ツールレベルエラーartifacts[].parts[].data.adcp_error— A2A タスクレベルエラー(アーティファクト)status.message.parts[].data.adcp_error— A2A タスクレベルエラー(ステータスメッセージ)error.data.adcp_error— JSON-RPC トランスポートレベルエラーadcp_errorキーを含む JSON パースされたcontent[].text— 古い MCP サーバー用のテキストフォールバック(isErrorレスポンスのみ)payload.errors[0](またはトップレベルerrors[0])— ペイロード層フォールバック。トランスポートエンベロープがadcp_errorを表面化しないがペイロードがerrors[]配列を運ぶ場合に使用。ペイロード層のみが設定される非致命的なケース(例: 警告を報告するinput-requiredタスク)ではペイロードからの読み取りは正当だが、ペイロード経由でのみエラーを表面化する致命的なタスクはエージェント側のコンフォーマンスギャップです。- 構造化エラーが見つからない — 汎用エラー処理にフォールバック
string 型の code フィールドがあることを検証しなければなりません。検証が失敗した場合は、構造化エラーが見つからないとして扱います。
Storyboard check: error_code 契約
Storyboard バリデーターは、エラーがどちらの層にも表面化し得るため、パス固有のアサーションではなく check: error_code を使用します。ランナー契約:
check: error_codeは、上記のクライアント検出順序を実行してエラーコードを解決します — 優先順位:adcp_error.code(トランスポート)→errors[0].code(ペイロード)。- どちらの層も
codeを運ばない場合、検証はerror_code_not_resolvableで失敗します。 - Storyboard 作成者はアサーションを特定のパス(例:
check: field_present, path: "errors")にピン留めすべきではありません(SHOULD NOT) — それはテストを 1 つの層に結合し、もう一方の層にエラーを表面化するエージェントに対して失敗します。Storyboard authoring — Asserting on errors を参照してください。
adcp_error オブジェクトを返す(範囲外の retry_after を含む)。クランプ、リトライロジック、その他の動作要件はアクション層で適用されます(リカバリー動作を参照)。
実際には、実装はまずトランスポートタイプで分岐し、関連するパスのみを確認します:
リカバリー動作
抽出後、recovery フィールドに基づいてリカバリーを適用する:
retry_after の境界: セラーは 1 から 3600 秒の retry_after 値を返さなければなりません。クライアントはこの範囲外の値をクランプしなければなりません: 1 未満は 1 に、3600 超は 3600 になります。非有限値(NaN、Infinity)は欠如として扱わなければなりません。これにより、設定が間違ったサーバーからの積極的なリトライループと病的に長いストールの両方を防ぐ。
リトライ上限: バイヤーエージェントはオペレーションごとに最大リトライ回数(例: 3 回)と最大累積リトライ時間(例: 300 秒)を強制すべきです。リトライバジェットを超えて持続する一時的エラーはターミナルとしてエスカレーションすべきです。上限なしでは、すべてのリクエストで retry_after: 3600 を返す悪意のある、または設定が間違ったセラーがエージェントを無期限に停滞させる可能性があります。
recovery が欠如している場合: 標準エラーコードテーブルを使用してコードベースの分類にフォールバックします。これにより、レベル 1 サーバー(code と message のみを返す)でも、対応するクライアントから正しいリカバリー動作を得られます。コードも不明の場合は、terminal として扱います。
未知の recovery 値(前方互換性)については、terminal として扱います。
推奨 details 形式
details フィールドはオープンオブジェクトです。相互運用性の発散を防ぐため、セラーは一般的なエラーコードの details を設定する際にこれらの標準キーを使用すべきだ:
RATE_LIMITED
BUDGET_TOO_LOW
AUDIENCE_TOO_SMALL
ACCOUNT_SETUP_REQUIRED
CREATIVE_REJECTED
POLICY_VIOLATION
CONFLICT
サイズガイダンス
セラーはdetails をコンパクトに保つべきです。エラーレスポンスは LLM コンテキストウィンドウを通じて流れ、すべてのトークンにコストがかかる — リトライをトリガーする一時的なエラーは1つの会話内で複数のエラーレスポンスを蓄積することがあります。ガイドラインとして、details を 500 シリアル化 JSON バイト未満に保つ(UTF-8 で JSON.stringify(details).length を使用 — 非 ASCII コンテンツには重要だ)。
details スキーマ
推奨される details 形式のすべての JSON スキーマはエラーコード列挙と一緒に公開されています:
/schemas/latest/error-details/rate-limited.json/schemas/latest/error-details/budget-too-low.json/schemas/latest/error-details/audience-too-small.json/schemas/latest/error-details/account-setup-required.json/schemas/latest/error-details/creative-rejected.json/schemas/latest/error-details/policy-violation.json/schemas/latest/error-details/conflict.json
details を完全に省略するセラーも適合しています。エージェントは特定の details キーを要求してはなりません — details が欠如または予期しない形状の場合は code、message、recovery にフォールバックします。
セラー固有のエラーコード
セラーは標準語彙にないエラーコードを使用してもよい。セラー固有のコードを標準コードと区別し、セラー間の衝突を避けるために:- セラー固有のコードは
X_{VENDOR}_{CODE}形式を使用しなければなりません(例:X_STREAMHAUS_FLOOR_NOT_MET) {VENDOR}はベンダーエラーコードレジストリに登録された大文字英数字識別子でなければなりません(/^[A-Z][A-Z0-9]{1,19}$/にマッチ){CODE}は大文字英数字とアンダースコアでなければなりません(/^[A-Z][A-Z0-9_]{1,39}$/にマッチ)- エージェントは不明なコードを
recovery分類にフォールバックして処理しなければなりません - 不明なコードで
recoveryが欠如している場合はterminalとして扱います - セラーは PR を提出することでベンダーエラーコードレジストリにベンダープレフィックスとコードを登録すべきです
クライアントライブラリ要件
この仕様を実装するクライアントライブラリ(@adcp/client など)は以下を満たさなければなりません:
-
構造化エラーを自動的に抽出します。 コンシューマーは、メッセージ文字列の汎用エラーではなく、
code、recovery、retryAfter、field、suggestion、detailsを持つ型付きエラーオブジェクトを受け取るべきです。 -
検出順序を実装します。 すべてのパスを順番に確認します:
structuredContent、アーティファクト、status.message.parts、error.data、テキストフォールバック。 -
抽出されたエラーを検証します。
codeが空でない文字列(最大 64 文字)であり、シリアル化されたペイロードの合計が 4096 バイトを超えないことを確認します。検証に失敗したペイロードは破棄します。 -
テキストフォールバックを
isErrorでガードします。isErrorがtrueの MCP レスポンスでのみ JSON ベースのテキスト抽出を試みる。JSON コンテンツを含む成功レスポンスをエラーとして解釈してはなりません。 -
リカバリーメタデータを保持します。 抽出されたエラーには
recoveryとretry_afterを含め、呼び出し元が再解析なしにリトライロジックを実装できるようにします。 -
未知のリカバリー値を処理します。 未知の
recovery値はterminalとして扱います。 -
retry_afterをクランプします。 1 未満は 1 に、3600 超は 3600 になります。非有限値(NaN、Infinity)は欠如として扱わなければなりません。 -
テキストフォールバックをサポートします。
structuredContentなしの MCPisErrorレスポンスのcontent[].textに対してJSON.parseを試みる。structuredContentの採用が広まるまで、これが主要な抽出パスになります。
retry_afterが存在する場合に指数バックオフでtransientエラーを自動リトライしてもよい- コンシューマーがリトライ動作を設定するための
retryPolicyオプションを公開してもよい STANDARD_ERROR_CODESテーブルを使用して標準エラーコードを型付きエラーサブクラスにマッピングしてもよい
テストベクター
機械可読のテストベクターは/static/test-vectors/transport-error-mapping.json で入手可能です。各ベクターには以下が含まれます:
transport:mcpまたはa2apath: 抽出パス(structuredContent、jsonrpc_error、text_fallback、artifact)response: トランスポート固有のレスポンスエンベロープexpected_error: 抽出されるべき AdCP エラー(またはレガシーサーバーの場合はnull)expected_action:retry、surface_to_caller、escalate_to_human、またはgeneric_error
エージェントチェーンでのエラー変換
セラーエージェントがアップストリームサービス(API、データベース、他のエージェント)を呼び出す場合、アップストリームの失敗は呼び出し元に返す前に変換しなければなりません。 ルール 1: アップストリームエラーを AdCP エラーコードに変換します。 生のアップストリームエラーをそのまま渡してはなりません。セラーの内部 API からの HTTP 429 はRATE_LIMITED になります。データベース接続タイムアウトは SERVICE_UNAVAILABLE になります。バイヤーは関係のないシステムのエラーフォーマットを見るべきではありません。
ルール 2: 呼び出し元の視点からリカバリーを分類します。 セラーがバイヤーのアクションなしにアップストリームの問題を修正できる場合、エラーは transient または terminal だ — correctable ではありません。correctable エラーはバイヤーが何かを変更する必要があることを意味します。例えば: セラーのアップストリームクリエイティブレビュー API が広告を拒否した場合、それは correctable(バイヤーはクリエイティブを修正できます)。しかしセラーの内部課金システムがダウンしている場合、アップストリームエラーが 500 であっても、それは transient(バイヤーはリトライすべき)だ。
ルール 3: 中間者は保持するか変換するが、決して削除しません。 バイヤーとセラーの間に座る中間者(例: 複数のセラーにルーティングするエージェンシーエージェント)は以下を行わなければなりません:
- アップストリームがすでに AdCP 準拠の場合は AdCP エラーを変換せずに渡す、または
- アップストリームが異なるフォーマットを使用している場合はエラーを有効な AdCP エラーに変換する
recovery、retry_after、または details を削除してはなりません。中間者は複数のアップストリームセラーからのエラーを errors 配列に集約してもよく、各エラーは元の code と recovery を保持します。
セキュリティ上の考慮事項
エラーレスポンスは LLM コンテキストを通じて流れる。すべてのフィールドはクライアント向けです。セラーの要件
実装は以下を含めてはなりません:- 内部サービス名、ホスト名、または IP アドレス
- データベースエラーテキスト、SQL フラグメント、またはクエリプラン
- スタックトレースまたはファイルパス
- 内部サービスからのアップストリーム API レスポンス
- 認証情報、トークン、またはセッション識別子
suggestion の境界: 特定の閾値、有効な識別子、リソースの存在を明かすのではなく、一般的な修正ガイダンス(例: “Increase budget to meet minimum”)を提供します。
retry_after の一貫性: タイミングサイドチャネルを避けるため、ターゲットリソースのプロパティではなく、呼び出し元のレートリミット状態を反映した一貫した値を返します。
トランスポートレベルコードの粒度: 予約済み JSON-RPC コード(-32029、-32028、-32027)はインフラエラーの分類を可能にします。エンドポイントのフィンガープリントを最小化したい実装は、これらを単一のコードに統合してもよい。
バイヤーエージェントの要件
エラーフィールドを通じたプロンプトインジェクション。message、suggestion、field、details、およびそれらの中のすべての文字列値は、バイヤーエージェントの LLM コンテキストに入るセラー制御コンテンツです。悪意のある、または侵害されたセラーは、バイヤーエージェントを操作することを目的とした指示を含む値を作成できます。
バイヤーエージェントは以下を行わなければなりません:
- すべてのリカバリー決定を
codeとrecoveryのみを通じてルーティングします。 アクション可能な指示のためにmessage、suggestion、またはdetails値を解析してはなりません。上記のhandleAdcpError関数はこのパターンを示している — メッセージコンテンツではなくrecoveryで切り替える。 - セラー提供の文字列にデータ境界を使用します。 エラーフィールド値を LLM コンテキストに含める場合、システムプロンプトが信頼できないセラーデータとして指定する明示的なデータデリミター(例: 構造化されたツールレスポンスフィールド、XML スタイルタグ)の内側に置く。セラー提供の文字列を散文や指示に補間しません。
- セラー文字列を LLM コンテキストに含める前に長さ制限を適用する:
message(256 バイト)、suggestion(512 バイト)。サイレントにトランケートします。 - すべての文字列フィールドから非印刷可能文字を除去する: 制御文字(U+0000–U+001F)、ゼロ幅文字(U+200B–U+200F)、双方向オーバーライド文字(U+202A–U+202E)。
- 最大ペイロードサイズを強制します。 クライアントは
JSON.stringify(error).lengthが 4096 バイトを超える抽出されたadcp_errorオブジェクトを破棄しなければなりません。これにより過大なdetailsオブジェクトによるコンテキストウィンドウの消耗を防ぐ。 - オブジェクトミューテーション操作でダイナミックプロパティパスとして
fieldを使用しない(例:lodash.set、ブラケット表記チェーン)。field値は表示とフィールドレベルの UI ハイライトのみ用です。 - キーをフィルタリングせずに
Object.assign、スプレッド演算子、またはシャローコピーを通じて抽出されたエラーオブジェクトをアプリケーション状態にマージしません。__proto__やconstructorなどのセラー制御キーは一部のランタイムでプロトタイプ汚染を引き起こす可能性があります。 - 生の
detailsオブジェクトをシステムプロンプトやツールの説明に含めない。
details.setup_url(ACCOUNT_SETUP_REQUIRED エラー内)は、アカウントセットアップを完了するためにユーザーまたはエージェントが辿ることができるセラー提供の URL だ。クライアントは setup_url が https スキームを使用し、ユーザー情報コンポーネントを含まず(例: https://user:pass@evil.com)、ドメインがセラーの既知のドメインと一致することを検証しなければなりません。これらの確認に失敗した URL は拒否しなければなりません。
details.policy_url(CREATIVE_REJECTED および POLICY_VIOLATION エラー内)は情報提供のみです。クライアントは同じ検証を適用すべきです。すべてのセラー提供 URL は https 以外のスキーム(http、javascript、data、file)を使用している場合は拒否しなければなりません。
関連情報
- エラーハンドリング — エラースキーマ、標準コード、リカバリー戦略
- MCP ガイド — MCP トランスポート統合
- A2A ガイド — A2A トランスポート統合
- A2A レスポンスフォーマット — 標準 A2A レスポンス構造