CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTSとは — ゲートウェイの400を避ける設定
CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS=1は、構造化出力用のoutput_config.formatと対のbeta値の送信だけを止める環境変数です。使う場面と効かない範囲をまとめます。
CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTSで止まるもの
CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTSは、Claude Codeが構造化出力(structured outputs)のために送るoutput_config.formatフィールドと、それと対になるanthropic-betaの値を送らなくする環境変数です。1を設定すると有効になります。対象はv2.1.288以降のClaude Codeです。
想定している場面は、ANTHROPIC_BASE_URLで指すLLMゲートウェイの上流が、このフィールドを拒否するケースです。Amazon BedrockやGoogle CloudのAgent Platformを上流にしたゲートウェイでは、output_configを名指しした400が返ることがあります。
止まるのは構造化出力の形式指定だけです。ほかのプレリリース機能は送られ続けます。この性質が、似た名前のCLAUDE_CODE_DISABLE_EXPERIMENTAL_BETASとの使い分けの軸になります。
v2.1.288で入った経緯
v2.1.288のchangelogには、セッションタイトル、メモリの呼び出し、プロンプトフックが、Mantleや構造化出力を拒否するゲートウェイの背後で失敗する不具合の修正が載っています。同じ項目に、この環境変数の追加も書かれています。
つまり、会話本体のリクエストではなく、Claude Codeが裏で投げる補助的なリクエストが構造化出力を使っていたことになります。セッションタイトルや記憶の呼び出しが失敗する、という形で症状が出ます。
一つ前のv2.1.287では、CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETASを設定していても、セッションタイトルとプロンプトフックのリクエストから構造化出力の形式が外れない問題が直っています。Bedrockを背にしたゲートウェイが、これを拒否していました。output_config.formatを外す機能そのものがv2.1.287でEXPERIMENTAL_BETAS側に入り、v2.1.288で単独の変数が加わった流れです。
ゲートウェイの互換性に関わる修正を、changelogの日付つきで並べます。
| バージョン | 日付 | 内容 |
|---|---|---|
| v2.1.280 | 日付2026年9月22日 | 内容アドバイザーツールを拒否する上流への再試行が入る |
| v2.1.287 | 日付2026年10月1日 | 内容DISABLE_EXPERIMENTAL_BETASがセッションタイトルとプロンプトフックの形式指定も外す |
| v2.1.288 | 日付2026年10月2日 | 内容補助リクエストの失敗を修正し、DISABLE_STRUCTURED_OUTPUTSを追加 |
以前にも似た症状はありました。v2.1.122のchangelogには、Vertex AIやBedrockがinvalid_request_error: output_config: Extra inputs are not permittedを返し、セッションタイトルの生成などが失敗する問題の修正が載っています。セッションタイトルの生成が構造化出力の拒否で失敗する型は、v2.1.288より前にも直されています。
前後のリリースの全体像はv2.1.288のリリースノートにあります。
症状から原因をたどる
構造化出力を使うのは、会話本体ではなく補助リクエストです。症状はコマンドの失敗ではなく、周辺機能の不調として現れます。
- セッションのタイトルが付かない
- メモリの呼び出しが働かない
- プロンプトフックが失敗する
この3つが、400と同時にゲートウェイのログへoutput_configの名前を残していたら、この変数の出番です。本文の会話は普通に進むので、気づくのが遅れがちです。
上流の種類でも出方が変わります。プロトコル解説の表では、output_configを名指しした400が出やすいのは、Amazon BedrockとGoogle CloudのAgent Platformを上流にしたゲートウェイです。context_managementの400が出やすいのも、Anthropic形式のリクエストを受けてBedrockへ転送するゲートウェイです。
Claude Codeが拒否を受けて自動で再試行するのは、一部のフィールドだけです。
| 拒否されたもの | Claude Codeの対応 |
|---|---|
thinkingフィールド | Claude Codeの対応再試行し、その会話の間は送らない |
| アドバイザーツール | Claude Codeの対応一度だけ再試行し、終了まで外す |
output_config.effort | Claude Codeの対応再試行し、終了までそのモデルで外す |
context_managementとツールのスキーマ | Claude Codeの対応再試行せず、400が利用者に届く |
output_config.format | Claude Codeの対応再試行の対象として載っていない |
構造化出力の形式指定は、再試行の一覧に載っていません。だからこそ、拒否されたら変数で止める選択肢が必要になります。
EXPERIMENTAL_BETASとの違い
どちらを選ぶかは、ゲートウェイが拒否しているものが何かで決まります。
| 項目 | DISABLE_STRUCTURED_OUTPUTS=1 | DISABLE_EXPERIMENTAL_BETAS=1 |
|---|---|---|
output_config.format | DISABLE_STRUCTURED_OUTPUTS=1送らない | DISABLE_EXPERIMENTAL_BETAS=1送らない(v2.1.287以降) |
output_config.task_budget | DISABLE_STRUCTURED_OUTPUTS=1送る | DISABLE_EXPERIMENTAL_BETAS=1送らない |
context_managementと対のbeta値 | DISABLE_STRUCTURED_OUTPUTS=1送る | DISABLE_EXPERIMENTAL_BETAS=1送らない |
ツールのbeta項目(strict、defer_loading) | DISABLE_STRUCTURED_OUTPUTS=1送る | DISABLE_EXPERIMENTAL_BETAS=1送らない |
| MCPツール検索 | DISABLE_STRUCTURED_OUTPUTS=1通常どおり | DISABLE_EXPERIMENTAL_BETAS=1無効になり、全MCPツールが先読みされる |
output_config.effort | DISABLE_STRUCTURED_OUTPUTS=1送る | DISABLE_EXPERIMENTAL_BETAS=1送る |
表のとおり、DISABLE_STRUCTURED_OUTPUTSはDISABLE_EXPERIMENTAL_BETASが止める項目のうち、output_config.formatの一つだけを止めます。EXPERIMENTAL_BETASのドキュメントには、MCPツール検索が無効になり、管理設定で維持しない限り全てのMCPツールが先読みされる、という副作用が書かれています。MCPサーバーを多く接続している環境では、この差が効いてきます。
拒否されたフィールドがoutput_config.formatだけだと分かっているなら、狭い変数から試すほうが失う機能が少なくて済みます。原因がはっきりしない400では、先に広い変数で症状が消えるかを見て、その後で狭い変数に絞る進め方もあります。
どちらの変数も、output_config.effortは止めません。effortを拒否する上流には別の仕組みがあり、Claude Codeは拒否を受けるとeffortを外して再試行し、Claude Codeを終了するまでそのモデルへの後続リクエストでも外し続けます。
設定のしかた
シェルから渡す方法と、設定ファイルのenvに書く方法があります。
export CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS=1
claude組織で配るなら、settings.jsonのenvキーに書きます。
{
"env": {
"CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS": "1"
}
}envの値は文字列で書きます。~/.claude/settings.jsonは自分の全プロジェクト、.claude/settings.jsonはプロジェクトの全員、managed settingsは組織全体に効きます。ゲートウェイを使う全員が同じ症状になるなら、managed settingsでの配布が向いています。この変数の説明には、設定ファイルのenvブロックを無視するという注記はありません。環境変数の一般的な置き場所は環境変数の一覧記事にまとめています。
設定する前に確かめたいこと
この変数が必要になる条件は、ゲートウェイの上流がoutput_config.formatを拒否していることです。次の順で切り分けられます。
設定が要るかどうかの切り分け
- 1
エラー文言のフィールド名を読む
400のメッセージがoutput_configを名指ししているかを見ます。Extra inputs are not permittedが添えられていることが多いパターンです。 - 2
設定後の挙動を手元で確かめる
この変数で止まるのは構造化出力の形式指定です。セッションタイトルなど、構造化出力を使う補助機能がどう振る舞うかは、環境変数の説明には書かれていません。設定後の挙動は手元で確かめてください。
- 3
バージョンを揃える
変数はv2.1.288以降でのみ有効です。古いClaude Codeが混ざる環境では、設定しても効かない端末が出ます。
- 4
再現と解消を同じ手順で見る
設定前と設定後で、同じ操作を1回ずつ行い、ゲートウェイのログに
output_configが載るかを比べます。
非対話モードのclaude -p --json-schemaを使う場合は、確認が一つ増えます。このオプションはスキーマに沿ったJSONを結果のstructured_outputフィールドに返す機能で、変数の説明はoutput_config.formatの送信停止だけを述べています。両者の関係は、どちらのドキュメントにも書かれていません。ゲートウェイ越しに--json-schemaを使うなら、変数を入れた状態で実際に流して、結果が返るかを確かめてください。
ゲートウェイ側で直せるなら、そちらが本筋です。ドキュメントは、フィールドとbeta値を対で転送し、ゲートウェイがリクエスト本文を書き換えないことを勧めています。片方だけが欠けると400になり、両方が欠けたときだけ機能が静かに切れるためです。変数は、転送の修正が間に合わないときの回避策という位置づけです。
エラー本文の扱いにも注意が必要です。Claude Codeの再試行は上流のエラー文言を照合して動くため、ゲートウェイは上流のエラーを書き換えずに返す必要があります。独自のエンベロープで包むと、ステータスコードが同じでも回復の経路が壊れます。包む場合は、メッセージにcapability_rejected:で始まる安定した印を入れる決まりです。
ゲートウェイ側で直すときの要点
変数に頼らず転送を直すなら、押さえる点は三つあります。
一つ目は、anthropic-*のリクエストヘッダーとリクエスト本文のフィールドを、許可リストで絞らずそのまま通すことです。Claude Codeはリリースのたびに新しいanthropic-betaの値や本文フィールドを足します。観測した一覧に固定したゲートウェイは、次の機能のヘッダーやフィールドを削り、その機能が入ったリリースで壊れます。ただし、BedrockやAgent Platformのように形式の違う上流では、スキーマの差を橋渡しするのがゲートウェイの仕事です。
二つ目は、本文を書き換えないことです。内容検査のために本文を書き換えたり伏せ字にしたりすると、ヘッダーを削ったときと同じく、本文とヘッダーの対が崩れて400になります。検査は変更なしで行います。
三つ目は、失敗の出方が機能で違う点です。拡張コンテキストとインターリーブ思考は本文のフィールドを持たず、ヘッダーだけで働きます。ヘッダーを削ると、エラーなしで機能が使えなくなります。対になる機能のほうは、片方だけ欠けると400、両方が欠けたときだけ静かに切れます。400が出ない不具合は、気づきにくいぶん厄介です。
構造化出力の形式指定は、この「対」の一つです。output_configの本文フィールドと、それ専用のanthropic-betaの値が一組で動きます。
設定しても直らないとき
この変数が外すのはoutput_config.formatと対のbeta値だけです。次のような400は、別の原因を疑います。
context_management、strict、defer_loadingといった別フィールドの拒否。CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETASの領分ですoutput_config.effortの拒否。Claude Code側の再試行が働くため、通常は変数なしで収まりますthinkingフィールドの拒否。アダプティブ推論にanthropic-betaのペアはなく、Opus 4.6とSonnet 4.6向けの別の変数がありますANTHROPIC_BETASやCLAUDE_CODE_EXTRA_BODYで自分が足した値。これらはEXPERIMENTAL_BETASでも外れません
ゲートウェイ側の互換性を全体で見直したいときは、LLMゲートウェイ互換性の解説が症状別の表を持っています。接続の初期設定はゲートウェイへの接続手順から始められます。
まとめ
CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS=1は、output_config.formatだけを狙って外すための変数です。拒否されているフィールドが構造化出力だけなら、この変数で十分です。複数のフィールドが拒否されるならCLAUDE_CODE_DISABLE_EXPERIMENTAL_BETASを検討します。ただし後者はMCPツール検索も止めます。