> ## Documentation Index
> Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
> Use this file to discover all available pages before exploring further.

# ストーリーボードトラブルシューティング

> AdCP コンプライアンスストーリーボードを実行するときの一般的な失敗パターン — 欠けているフィクスチャ、署名チャレンジ、エンベロープドリフト、コンテキストエコー、ケイパビリティ不一致、ステートマシンエラーコード。

コンプライアンスストーリーボードがエージェントに対して失敗すると、ランナーはステップ名とエラーテキストをレポートします。このページは、最も一般的なエラーパターンをその根本原因と修正にマップし、SDK ソースやランナー内部を探検せずに各失敗クラスを解決できるようにします。

各セクションは、あなたが見るエラー、その意味、エージェントで何を変えるかを示します。

## Unknown fixture エラー

```
× (unknown step): PRODUCT_NOT_FOUND: Package 0: Product not found: test-product
```

ストーリーボードの `sample_request` はハードコードされた ID（`test-product`、`test-pricing`、`campaign_hero_video`、`gov_acme_q2_2027` など）を参照します。ランナーは、変更ステップが実行される前にエージェントがその ID をカタログに持つことを期待します。

**修正:** `comply_test_controller` を実装し、ストーリーボードの `fixtures:` ブロックで宣言されたシードシナリオを尊重します。`prerequisites.controller_seeding: true` が設定されると、ランナーは、メインフェーズが実行される前に外部キー順で `seed_product`、`seed_pricing_option`、`seed_creative`、`seed_plan`、`seed_media_buy` を呼ぶフィクスチャフェーズを自動注入します。

完全なシードコントラクトについては [コンプライアンステストコントローラー — シナリオ](/docs/building/by-layer/L3/comply-test-controller#scenarios) を参照。シード呼び出しで `UNKNOWN_SCENARIO` を返すエージェントは、ストーリーボードを `not_applicable` とグレードします — 欠けているサンドボックスサーフェスでペナルティを受けませんが、事前シードされた状態に依存するストーリーボードを通過できません。

## 401 で署名チャレンジが欠けている

```
× (unknown step): expected error="request_signature_required", got error="(none)"
```

ストーリーボードは `get_adcp_capabilities.request_signing.required_for` で宣言された操作に未署名リクエストを送りました。エージェントは 401 で拒否しましたが `WWW-Authenticate: Signature ...` チャレンジヘッダーを含めなかったため、ランナーはトランスポートバインディングからエラーコードを解決できませんでした。

**修正:** 欠けているまたは無効な署名によって引き起こされるすべての 401 で RFC 9421 チャレンジヘッダーを発します。ランナーはトランスポートバインディング順序経由でエラーコードを解決します — `WWW-Authenticate` ヘッダーが欠けている場合、JSON ボディが有用なメッセージを運んでもエラー分類は「(none)」にフォールバックします。

リファレンス SDK は、これらのエラーを `@adcp/sdk/signing` の `RequestSignatureError` 経由で `.code: RequestSignatureErrorCode` で構築します。完全なタクソノミー（`request_signature_required`、`request_signature_header_malformed`、`request_signature_tag_invalid`、`request_signature_window_invalid`、`request_signature_key_unknown` など）はそのモジュールで列挙されます。エージェントは、SDK を話す呼び出し元が自動的に回復できるよう、チャレンジで同じコードをサーフェスすべきです（SHOULD）。

チャレンジヘッダー形式については [署名付きリクエスト（トランスポート層）](/docs/building/by-layer/L1/security#署名付きリクエストトランスポート層) と [transport-error バインディング順序](/docs/building/operating/transport-errors) を参照。

## レスポンスエンベロープドリフト

```
× (unknown step): Response contains errors array
```

ベクターは `check: error_code` を使いましたが、あなたのレスポンスはランナーのクライアント検出順序が期待しなかった形状でエラーをサーフェスします。実際には、これはトランスポート層が既に `adcp_error` を運んでいたときエージェントが `errors[]` を返した（またはその逆）ことを意味します — ストーリーボードは単一のエラーコードをアサートし、ランナーはあなたが発したのと異なる層からそれを解決しました。

**修正:** [エンベロープ対ペイロードの 2 層モデル](/docs/building/by-layer/L3/error-handling#envelope-vs-payload-errors-the-two-layer-model) に従い、レスポンスごとに 1 つのエラーサーフェスを選び、それに固執します。MCP: 構造化コンテンツには `adcp_error`、タスクペイロードエラーには `errors[]`。A2A: 同じ層が適用 — エンベロープのトランスポートエラー、タスクアーティファクトの DataPart のアプリケーションエラー。

ランナーの `check: error_code` は形状非依存 — どちらの層からも解決する — が、エージェントが両方を同時に発すると不一致になりえ、ランナーは解決されたコードをベクターの期待に対してグレードします。1 つのサーフェスを選び一貫していれば分岐を避けます。

## コンテキストエコー失敗

```
× (unknown step): expected field "context.correlation_id" = "xyz", got (missing)
```

エージェントはリクエストの `context:` オブジェクトを含まないレスポンスを返しました。`context: { correlation_id: ... }` を送るすべてのストーリーボードステップは、`context.correlation_id` がレスポンスで変更なくエコーされることをアサートします。

**修正:** エラーを含むすべてのレスポンスで完全な `context:` オブジェクトを逐語的に保持します。エコーコントラクトは規範的 — バイヤーは `correlation_id` を使ってマルチエージェントフローをつなぎ、ランナーはすべてのコンテキストを運ぶステップをそれでグレードします。[Context and sessions — 規範的エコーコントラクト](/docs/building/by-layer/L2/context-sessions#normative-echo-contract) を参照。

キャプチャは同じコントラクトを逆に使います: `context_outputs:` を通じて `"$context.<name>"` を渡すストーリーボードは、プロデューサーステップの検証が通過した後にキャプチャが投入されることに依存します。プロデューサーが失敗または `context:` を省略したとき `$context.foo` を読む下流ステップは `unresolved_substitution` とグレードされます。

## ケイパビリティベクター不一致（ランナーが宣言、エージェントがサポートしない）

```
× (unknown step): capability X asserted but not declared in get_adcp_capabilities
```

ストーリーボードは、エージェントがその `get_adcp_capabilities` レスポンスでアドバタイズしないケイパビリティを要求するステップをディスパッチしました。ランナーはこれらのステップを自動スキップすべきです。代わりに失敗としてグレードされているのを見ている場合、ケイパビリティが誤ったキーで宣言されているか、ランナーが自動スキップパスを欠いています。

**修正:** `get_adcp_capabilities.tools` リストと任意の required-for フィールド（`request_signing.required_for`、`idempotency.supported_tools` など）を再確認します。専門化エージェントにのみ適用されるベクターについては、ストーリーボード作者が `skipVectors` を使ってオプトアウトを明示的にフラグできます。実装者として、修正はほぼ常にベクターではなくケイパビリティ宣言にあります。

## required-for 合成

```
× (unknown step): missing auth — step requires authenticated or signed
```

ランナーは、認証された認証情報または署名付きリクエストのいずれかを期待する変更ステップに遭遇し、トランスポートがどちらも運びませんでした。通常これは、テストキットが `auth.api_key` または `auth.basic` を宣言せず **かつ** エージェントがリクエスト署名サポートをアドバタイズしないことを意味します — ランナーに呼び出しを認証する方法を残しません。

**修正:** (a) ランナーが静的な Authorization ヘッダー認証情報を使うようテストキットに `auth.api_key` または `auth.basic` を宣言するか、(b) ランナーが代わりにリクエストに署名するよう `get_adcp_capabilities.request_signing` 経由でリクエスト署名をアドバタイズします。ランナーの `requireAuthenticatedOrSigned` ゲートはどちらのパスも受け入れます — 両方が欠けているときのみ失敗します。

## Static-credential agent: no auth mechanism contributed (assert\_mechanism)

```json theme={null}
{
  "check": "assertion",
  "passed": false,
  "description": "Probe validations failed.",
  "expected": ["auth_mechanism_verified"],
  "actual": []
}
```

`mechanism_required` フェーズが、任意の optional auth フェーズから `auth_mechanism_verified` への寄与を見つけませんでした。これは静的認証情報のみのエージェント（Bearer API キーまたは HTTP Basic）の最も一般的な失敗で、実際の auth 問題ではありません — テストキット設定のギャップです。

**何が起こったか:** `api_key_path` フェーズは `skip_if: "!test_kit.auth.api_key"` を持ち、`basic_path` フェーズは `skip_if: "!test_kit.auth.basic"` を持ちます — それぞれ、テストキットが一致する認証情報を宣言しない限りスキップされます。`oauth_discovery` フェーズは `/.well-known/oauth-protected-resource/...` で 404 になります（静的認証情報のみのエージェントに期待される。それらの失敗はランナーによって黙って無視される）。すべての optional auth フェーズが何も寄与しないと、`assert_mechanism` は `actual: []` を見ます。

**`--auth TOKEN` の区別:** ランナーに渡す `--auth TOKEN` フラグはランナー自身のセッション認証情報です — あなたのエージェントへのランナー自身のリクエストを認可します。それは、静的認証情報フェーズが肯定的および無効認証情報プローブ中に送る特定の認証情報である `test_kit.auth.api_key` や `test_kit.auth.basic` とは完全に別です。これらは同じトークンではなく交換可能でありません。

**Bearer API キーエージェントの修正:** すべてのデフォルト AdCP ブランドテストキットは、`demo-<kit>-v1` 命名規則を使って `auth.api_key` の下にそのプローブ API キーを宣言します。デフォルトテストキット（`acme-outdoor`）は `demo-acme-outdoor-v1` を使います。キットのプローブキーを本番鍵と並んで有効なコンプライアンステスト認証情報として受け入れるようエージェントを設定します。`demo-<kit>-` プレフィックスが AdCP 適合性ハンドルです — 対して実行するキットのプレフィックスに一致する任意の Bearer トークンを受け入れます（サフィックスは仕様バージョンをまたいでローテートでき、プレフィックスは安定のまま）:

```typescript theme={null}
serve({
  authenticate: verifyApiKey({
    keys: {
      [PRODUCTION_TOKEN]: { principal: 'my-principal' },
      // Accept the default compliance kit's probe key (and any future suffix rotation)
      'demo-acme-outdoor-v1': { principal: 'compliance-runner' },
    }
  })
})
```

**HTTP Basic エージェントの修正:** `username`/`password` またはエンコードされていない `username:password` ペアを含む単一の `credentials` 値のいずれかで `auth.basic` を宣言するテストキットを使います。その Basic 認証情報を本番 Basic 認証情報と並んで有効なコンプライアンステスト認証情報として受け入れるようエージェントを設定します。`basic_path` フェーズは次に有効な Basic 認証情報とランダム無効な Basic 認証情報を送り、エージェントが有効な認証情報を受け入れ無効なものを拒否するときのみ `auth_mechanism_verified` を寄与します。

自身の本番認証情報のみを受け入れるエージェントは、一致する静的パスをスキップし（テストキット認証情報が一致しない）、`oauth_discovery` に失敗し（PRM なし）、`assert_mechanism` で `actual: []` に着地します。テストキット認証情報を許可された認証情報セットに追加すれば十分です — PRM エンドポイントや OAuth 発行者は不要です。

OAuth フェーズを「通過」するために存在しない発行者を指す偽の `/.well-known/oauth-protected-resource/...` を提供しないでください。それは、ストーリーボードが捕まえるよう設計された advertised-but-unserved 失敗モードをトリガーします。

carve-out がなぜ存在するか、静的認証情報 / `oauth_discovery` フェーズセマンティクスがどう設計されたかの背景については、[既知の仕様の曖昧さ — 非 OAuth エージェントに必要な PRM](/docs/building/cross-cutting/known-ambiguities#prm-required-for-non-oauth-agents) を参照。

## `INVALID_STATE` 対 `INVALID_TRANSITION`

混同しやすい 2 つのコード:

* **`INVALID_STATE`** — 「リソースがこのアクションを許さない状態にある」の正準 AdCP メディアバイエラーコード。要求されたように遷移できないメディアバイに対する `create_media_buy`/`update_media_buy`/`pause`/`resume`/`cancel` で使う。権威ある使用については `media-buy/specification.mdx` と `media-buy/media-buys/index.mdx` を参照。
* **`INVALID_TRANSITION`** — `comply_test_controller` サンドボックスプリミティブに固有。ランナーがセラーが拒否するステートマシン遷移を要求するとき（例: `active` を通らずに `approved` → `archived` を強制）に発せられる。[コンプライアンステストコントローラー — シナリオ](/docs/building/by-layer/L3/comply-test-controller#scenarios) を参照。

本番タスクで `INVALID_STATE` をアサートするストーリーボードベクターに対してエージェントが `INVALID_TRANSITION` を返すのはエラーコード語彙の不一致です — `INVALID_TRANSITION` は `static/schemas/source/enums/error-code.json` の正準 enum になく、コンプライアンステストコントローラーの外に現れるべきではありません。

## 上記のいずれも一致しないとき

ここの何にもマップしない失敗に遭遇した場合、[既知の仕様の曖昧さ](/docs/building/cross-cutting/known-ambiguities) ページを確認してください — 一部のストーリーボードは解決済みだが未リリースの仕様ギャップでブロックされ、回避策はそこで追跡されます。

まだ詰まっている？ 完全なランナー出力とストーリーボード名とともに [adcontextprotocol/adcp](https://github.com/adcontextprotocol/adcp/issues) で issue を提出してください。メンテナーは通常、エラーシグネチャからパターンを絞れます。
