Skip to main content
AdCP エラーはアプリケーション層のエラーです。トランスポートエラーチャネルではなく、ツール/タスクレスポンスに属します。このページでは 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" を使用します:
これはA2A レスポンスフォーマットの規則に従う: 最終状態はデータに .artifacts を使用します。 「ラッパーなし」ルールとの関係。 adcp_error キーは失敗したタスクの意図的な例外です。成功レスポンスの DataPart がタスク固有のデータ(例: products)を含むのとは異なり、失敗したタスクの DataPart はエラーのみを含みます。このキーは型の識別子として機能し、クライアントがステータスだけに頼ることなくエラーと成功ペイロードを区別できるようにします。

エラー MIME タイプ(オプション)

A2A エージェントはエラー DataPartmetadata.mimeType を設定してもよい:
クライアントは MIME タイプを必要としてはなりません。adcp_error キーが権威あるシグナルです。

エンベロープ vs. ペイロードエラー

AdCP はエラーを 2 つの異なる場所で公開します。本ページはトランスポートエンベロープadcp_error)を扱います。ペイロードエラー配列errors[])は Error Handling — Envelope vs. payload errors で扱います。 致命的なタスク失敗は両方の層を設定すべきです(SHOULD) — 正規の protocol-envelope.json の例と、規範的な SHOULD については error-handling.mdx リファレンスを参照してください。

クライアント検出順序

クライアントはこの順序で AdCP エラーを確認しなければなりません:
  1. structuredContent.adcp_errorisError: true 付き)— MCP ツールレベルエラー
  2. artifacts[].parts[].data.adcp_error — A2A タスクレベルエラー(アーティファクト)
  3. status.message.parts[].data.adcp_error — A2A タスクレベルエラー(ステータスメッセージ)
  4. error.data.adcp_error — JSON-RPC トランスポートレベルエラー
  5. adcp_error キーを含む JSON パースされた content[].text — 古い MCP サーバー用のテキストフォールバック(isError レスポンスのみ)
  6. payload.errors[0](またはトップレベル errors[0])— ペイロード層フォールバック。トランスポートエンベロープが adcp_error を表面化しないがペイロードが errors[] 配列を運ぶ場合に使用。ペイロード層のみが設定される非致命的なケース(例: 警告を報告する input-required タスク)ではペイロードからの読み取りは正当だが、ペイロード経由でのみエラーを表面化する致命的なタスクはエージェント側のコンフォーマンスギャップです。
  7. 構造化エラーが見つからない — 汎用エラー処理にフォールバック
クライアントは抽出されたエラーに 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 を参照してください。
抽出 vs アクション。 上記の検出順序は抽出層だ — フィールド値をそのまま保持した生の adcp_error オブジェクトを返す(範囲外の retry_after を含む)。クランプ、リトライロジック、その他の動作要件はアクション層で適用されます(リカバリー動作を参照)。 実際には、実装はまずトランスポートタイプで分岐し、関連するパスのみを確認します:

リカバリー動作

抽出後、recovery フィールドに基づいてリカバリーを適用する: retry_after の境界: セラーは 1 から 3600 秒の retry_after 値を返さなければなりません。クライアントはこの範囲外の値をクランプしなければなりません: 1 未満は 1 に、3600 超は 3600 になります。非有限値(NaNInfinity)は欠如として扱わなければなりません。これにより、設定が間違ったサーバーからの積極的なリトライループと病的に長いストールの両方を防ぐ。 リトライ上限: バイヤーエージェントはオペレーションごとに最大リトライ回数(例: 3 回)と最大累積リトライ時間(例: 300 秒)を強制すべきです。リトライバジェットを超えて持続する一時的エラーはターミナルとしてエスカレーションすべきです。上限なしでは、すべてのリクエストで retry_after: 3600 を返す悪意のある、または設定が間違ったセラーがエージェントを無期限に停滞させる可能性があります。 recovery が欠如している場合: 標準エラーコードテーブルを使用してコードベースの分類にフォールバックします。これにより、レベル 1 サーバー(codemessage のみを返す)でも、対応するクライアントから正しいリカバリー動作を得られます。コードも不明の場合は、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 スキーマはエラーコード列挙と一緒に公開されています: これらのスキーマは推奨であり、必須ではありません。details を完全に省略するセラーも適合しています。エージェントは特定の details キーを要求してはなりません — details が欠如または予期しない形状の場合は codemessagerecovery にフォールバックします。

セラー固有のエラーコード

セラーは標準語彙にないエラーコードを使用してもよい。セラー固有のコードを標準コードと区別し、セラー間の衝突を避けるために:
  • セラー固有のコードは 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 など)は以下を満たさなければなりません:
  1. 構造化エラーを自動的に抽出します。 コンシューマーは、メッセージ文字列の汎用エラーではなく、coderecoveryretryAfterfieldsuggestiondetails を持つ型付きエラーオブジェクトを受け取るべきです。
  2. 検出順序を実装します。 すべてのパスを順番に確認します: structuredContent、アーティファクト、status.message.partserror.data、テキストフォールバック。
  3. 抽出されたエラーを検証します。 code が空でない文字列(最大 64 文字)であり、シリアル化されたペイロードの合計が 4096 バイトを超えないことを確認します。検証に失敗したペイロードは破棄します。
  4. テキストフォールバックを isError でガードします。 isErrortrue の MCP レスポンスでのみ JSON ベースのテキスト抽出を試みる。JSON コンテンツを含む成功レスポンスをエラーとして解釈してはなりません。
  5. リカバリーメタデータを保持します。 抽出されたエラーには recoveryretry_after を含め、呼び出し元が再解析なしにリトライロジックを実装できるようにします。
  6. 未知のリカバリー値を処理します。 未知の recovery 値は terminal として扱います。
  7. retry_after をクランプします。 1 未満は 1 に、3600 超は 3600 になります。非有限値(NaNInfinity)は欠如として扱わなければなりません。
  8. テキストフォールバックをサポートします。 structuredContent なしの MCP isError レスポンスの content[].text に対して JSON.parse を試みる。structuredContent の採用が広まるまで、これが主要な抽出パスになります。
クライアントライブラリは追加で:
  • retry_after が存在する場合に指数バックオフで transient エラーを自動リトライしてもよい
  • コンシューマーがリトライ動作を設定するための retryPolicy オプションを公開してもよい
  • STANDARD_ERROR_CODES テーブルを使用して標準エラーコードを型付きエラーサブクラスにマッピングしてもよい

テストベクター

機械可読のテストベクターは /static/test-vectors/transport-error-mapping.json で入手可能です。各ベクターには以下が含まれます:
  • transport: mcp または a2a
  • path: 抽出パス(structuredContentjsonrpc_errortext_fallbackartifact
  • response: トランスポート固有のレスポンスエンベロープ
  • expected_error: 抽出されるべき AdCP エラー(またはレガシーサーバーの場合は null
  • expected_action: retrysurface_to_callerescalate_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 エラーに変換する
中間者は渡すエラーから recoveryretry_after、または details を削除してはなりません。中間者は複数のアップストリームセラーからのエラーを errors 配列に集約してもよく、各エラーは元の coderecovery を保持します。

セキュリティ上の考慮事項

エラーレスポンスは LLM コンテキストを通じて流れる。すべてのフィールドはクライアント向けです。

セラーの要件

実装は以下を含めてはなりません:
  • 内部サービス名、ホスト名、または IP アドレス
  • データベースエラーテキスト、SQL フラグメント、またはクエリプラン
  • スタックトレースまたはファイルパス
  • 内部サービスからのアップストリーム API レスポンス
  • 認証情報、トークン、またはセッション識別子
suggestion の境界: 特定の閾値、有効な識別子、リソースの存在を明かすのではなく、一般的な修正ガイダンス(例: “Increase budget to meet minimum”)を提供します。 retry_after の一貫性: タイミングサイドチャネルを避けるため、ターゲットリソースのプロパティではなく、呼び出し元のレートリミット状態を反映した一貫した値を返します。 トランスポートレベルコードの粒度: 予約済み JSON-RPC コード(-32029-32028-32027)はインフラエラーの分類を可能にします。エンドポイントのフィンガープリントを最小化したい実装は、これらを単一のコードに統合してもよい。

バイヤーエージェントの要件

エラーフィールドを通じたプロンプトインジェクション。 messagesuggestionfielddetails、およびそれらの中のすべての文字列値は、バイヤーエージェントの LLM コンテキストに入るセラー制御コンテンツです。悪意のある、または侵害されたセラーは、バイヤーエージェントを操作することを目的とした指示を含む値を作成できます。 バイヤーエージェントは以下を行わなければなりません:
  • すべてのリカバリー決定を coderecovery のみを通じてルーティングします。 アクション可能な指示のために messagesuggestion、または 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 オブジェクトをシステムプロンプトやツールの説明に含めない。
URL 検証。 details.setup_urlACCOUNT_SETUP_REQUIRED エラー内)は、アカウントセットアップを完了するためにユーザーまたはエージェントが辿ることができるセラー提供の URL だ。クライアントは setup_urlhttps スキームを使用し、ユーザー情報コンポーネントを含まず(例: https://user:pass@evil.com)、ドメインがセラーの既知のドメインと一致することを検証しなければなりません。これらの確認に失敗した URL は拒否しなければなりません。 details.policy_urlCREATIVE_REJECTED および POLICY_VIOLATION エラー内)は情報提供のみです。クライアントは同じ検証を適用すべきです。すべてのセラー提供 URL は https 以外のスキーム(httpjavascriptdatafile)を使用している場合は拒否しなければなりません。

関連情報