Claude Agent SDKでOpus 5.5がAPI Error 400になる原因と対処法
claude-agent-sdk(Python)でmodel="claude-opus-5-5"を指定すると400エラーになる原因は、SDKが同梱するCLIバージョンの古さです。修正済みの版、成功扱いで返る見分け方、回避策を示します。
Claude Agent SDKで「API Error 400」が起きる原因
Python版のClaude Agent SDK(claude-agent-sdk)でmodel="claude-opus-5-5"を指定すると、実行のたびに次のエラーで止まることがあります。
API Error: 400 Claude Code 2.1.202 does not support this model; version 2.1.280 or newer is required. Run 'claude update', or update the Claude desktop app, then try again.原因はSDKが同梱するClaude Code CLIの古さです。claude-agent-sdkはPythonパッケージの中にCLIの実行バイナリを抱えており、cli_pathを指定しない限り、その同梱バイナリでセッションを起動します。Opus 5.5(claude-opus-5-5)はCLI 2.1.280以降でしか受け付けられず、古いCLIから来たリクエストはモデル名を渡した瞬間にAPIが400で拒否します。
この400はSDK固有のものではありません。Claude Codeの公式エラー一覧では、同じ文面がエラーコードclaude_code_version_too_oldの400として載っています。モデルごとの最低バージョンはサーバー側が判定し、APIが見るのは「リクエストを出したバイナリが名乗るバージョン」です。Claude Codeを自分で入れた人はclaude updateで済みますが、SDKが同梱するバイナリはclaude updateでは変わりません。SDKパッケージを上げて、アプリを再起動する必要があります。
組織のポリシーで最低バージョンが決まっている場合は、別の文面になります。is older than the minimum version required by your organization's policyと出るのがそのケースで、SDKを上げる前にポリシー側の下限を確認する場面です。SDKに限らない一般の切り分けはClaude Code does not support this modelで400になる原因と更新手順にあります。
エラーが「成功」として返ってくる
厄介なのは、成功に見える結果メッセージが先に流れてくることです。公式のPython SDKリファレンスによると、ResultMessageはsubtype="success"のままis_error=Trueになります。api_error_statusにはHTTPステータスが入ります。エージェントのループ自体は完走し、最後のAPI呼び出しだけが失敗した状態です。
関連するissue #1156(SDK 0.2.108)では、同じ形でerrorsが空配列のまま返る例が報告されています。当時のエラー文はClaude Code returned an error result: successで、失敗なのか成功なのか読み取れませんでした。現在のSDKは、結果の文面やAPI error (HTTP 400)を使います。今回のissue #1281の報告者も、モデル未対応の400が成功したターンに見えたと書いています。
結果メッセージの後には、例外も届きます。公式リファレンスでは、ResultErrorが最終のResultMessageの後に送出されると説明されています。Claude Codeのプロセスがエラー結果で終了したときで、ターン数の上限やAPIエラーが例です。Python SDK 0.2.140以降が対象です。
例外だけを見る実装は、先に流れるResultMessageのapi_error_statusを見落とします。結果メッセージも見て判定します。
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async for m in query(prompt="hi", options=ClaudeAgentOptions(model="claude-opus-5-5")):
if isinstance(m, ResultMessage) and m.is_error:
raise RuntimeError(f"turn failed: status={m.api_error_status} detail={m.result}")resultが空のことがあるため、公式リファレンスは直前のAssistantMessageの中身も合わせて見るよう勧めています。terminal_reasonはsubtypeより先に見る項目で、APIエラーでは"api_error"になります。api_error_statusが400でモデル名がOpus 5.5なら、まず同梱CLIのバージョンを疑う、という切り分けになります。
発端から修正までの時系列
issue #1281が立ったのは、CLI 2.1.280の公開から約4時間40分後でした。時刻はいずれもUTCです。
9月18日〜23日にあった出来事
- 9月18日 18:21SDK 0.2.157を公開
この時点のSDKでは、Opus 5.5を呼べません。
- 9月22日 15:44CLI 2.1.280がnpmに公開
Opus 5.5が追加され、Opus系の既定モデルになりました。
- 9月22日 20:26issue #1281が立つ
「公開済みのどのSDKもOpus 5.5を動かせない」という報告です。
mainには同梱CLIを2.1.280へ上げるコミットがすでにあり、そのコミットのE2Eテストが失敗していたため、リリースが止まっている可能性が指摘されています(#1280)。 - 9月23日 01:39SDK 0.2.158を公開
Opus 5.5が通るようになりました。日本時間では9月23日の10:39です。
Opus 5.5の料金や仕様変更はClaude Opus 5.5とはにあります。changelogでは2.1.280の項に、1Mコンテキスト・入出力$4/$20(1Mトークンあたり)・キャッシュ読み取り$0.20と書かれています。
同梱CLIのバージョン早見表
claude-agent-sdkは同梱CLIのバージョンをclaude_agent_sdk/_cli_version.pyに書いています。PyPIのwheelを展開して、manylinux_2_17_x86_64版の中身を各版で読んだ結果が次の表です。Windows列は、その版のPyPIにwin_amd64のwheelがあるかを示します。
| SDK | 同梱CLI | Opus 5.5 | PyPI公開(UTC) | Windows wheel |
|---|---|---|---|---|
| 0.2.156 | 同梱CLI2.1.276 | Opus 5.5使えない | PyPI公開(UTC)09-18 02:27 | Windows wheelあり |
| 0.2.157 | 同梱CLI2.1.277 | Opus 5.5使えない | PyPI公開(UTC)09-18 18:21 | Windows wheelなし |
| 0.2.158 | 同梱CLI2.1.280 | Opus 5.5使える | PyPI公開(UTC)09-23 01:39 | Windows wheelあり |
| 0.2.159 | 同梱CLI2.1.281 | Opus 5.5使える | PyPI公開(UTC)09-23 20:26 | Windows wheelあり |
| 0.2.160 | 同梱CLI2.1.283 | Opus 5.5使える | PyPI公開(UTC)09-25 22:31 | Windows wheelなし |
| 0.2.163 | 同梱CLI2.1.286 | Opus 5.5使える | PyPI公開(UTC)09-30 19:46 | Windows wheelなし |
issueの報告者がヒットしたのは0.2.111(同梱CLI 2.1.202)で、同じ制約が0.2.157まで続いていました。0.2.161と0.2.162も0.2.160と同じくWindows wheelはありません。同梱CLIはそれぞれ2.1.284と2.1.285です。
見落としやすいのは右端の列です。wheelはプラットフォームごとに別ファイルで、同じ版番号でも全OS分がそろうとは限りません。
Windowsにwheelがない版では、pipはsdist(ソース配布物)を取りに行きます。sdistの_bundled/にCLIの実行ファイルは入っていません。それでも_cli_version.pyは版数を持つため、0.2.160なら先のワンライナーは2.1.283と返します。
Windowsでは、入ったのがwheelかどうかと、claude_agent_sdk/_bundled/に実行ファイルがあるかを見ます。空なら、後述のcli_pathで2.1.280以降のCLIを渡します。
手元の環境を確認して直す
直す手順は短く、先に同梱CLIを読むところから始めます。
400を直す三手
- 1
いま入っているSDKの同梱CLIを読む
2.1.280未満なら原因はこれです。 - 2
SDKを上げて、アプリを再起動する
古い版が固定されている環境では、ロックファイルやイメージのキャッシュも更新します。
- 3
同梱CLIを読み直す
2.1.280以上になっていれば、model="claude-opus-5-5"は通ります。
python -c "from claude_agent_sdk._cli_version import __cli_version__; print(__cli_version__)"
python -c "import os, claude_agent_sdk as m; print(os.listdir(os.path.join(os.path.dirname(m.__file__), '_bundled')))"
pip install --upgrade "claude-agent-sdk>=0.2.158"
python -c "from claude_agent_sdk._cli_version import __cli_version__; print(__cli_version__)"uvで管理しているならuv pip install --upgrade、pyproject.tomlで固定しているなら上限を緩めてロックファイルを更新します。DockerイメージやCIでは、pipのキャッシュが古いwheelを再利用することがあります。pip install --no-cache-dir --upgrade claude-agent-sdkで入れ直すと、同梱CLIが上がらない原因を1つ消せます。
Claude Code本体のCLIは、別の話です。現行は2.1.287で、claude --versionで版を出し、claude updateで更新します。SDKの同梱バイナリはこの経路では更新されません。
すぐに上げられないときの回避策
アップグレードできない事情があるときの回避策は、issue #1281の報告者が2つ挙げています。
アップグレードできないときの2つの道
Opus 5を指定する
model="claude-opus-5"のように旧モデルを明示します。報告者が挙げた回避策で、Opus 5.5の機能がまだ要らない場合に手間が少ない形です。Opus 5はCLI 2.1.219で追加されたモデルです。
opusのようなエイリアスはCLI側が解決します。2.1.219から2.1.279までは(Anthropic APIで)Opus 5を指し、2.1.280でOpus 5.5に切り替わります。そのため2.1.280未満の同梱CLIでは、Opus 5.5を指しません。
cli_pathで外部CLIを渡す
ClaudeAgentOptions(cli_path="/path/to/claude")で、2.1.280以降のCLIを直接指します。which claudeで出たパスをそのまま渡し、claude --versionで版を確かめます。SDKが同梱版とは別のCLIで動くことになるため、issueでもその点が注意として挙がっています。
公式のエラー一覧には、ClaudeSDKClientのset_model()でOpus 5.5以外のモデルへ切り替え、同じセッションで続ける手も載っています。query()では使えません。
どちらも当座の手当てです。query()とClaudeSDKClientのどちらでもClaudeAgentOptionsの扱いは変わらないため、実装の選び方はquery() vs ClaudeSDKClient — Python Agent SDKの使い分けに譲ります。
issueがopenのままでも直っている
issue #1281は、0.2.158の公開後もGitHub上で「open」のままです。9月25日(UTC)には別の開発者が「自分のプロジェクトでも最新のOpusが使えない」とコメントしていますが、0.2.158はその2日前に出ています。issueの状態は修正の有無と連動しないことがあります。
issueのタイトルが「どの公開版もOpus 5.5に対応していない」という9月22日時点の事実を指しているため、今はそれが古くなっている、というのが実態です。判断はissueの状態でなく、PyPIの版と_cli_version.pyの値で行います。
新しいモデルでも同じ型で起きる
モデルごとの最低バージョンはサーバー側が持っています。公式のモデル設定ページには、Opus 5.5は2.1.280以降、Sonnet 5.5は2.1.284以降と書かれていて、Sonnet 5.5を同梱CLI 2.1.283以前のSDKで呼べば、同じ型の400が出ます。表のとおり、2.1.283を同梱する0.2.160はその一例です。
claude-agent-sdkを固定している運用では、新モデルの発表を見たら同梱CLIの値を読み、モデルページの最低バージョンと比べます。CIに先ほどのワンライナーを入れ、許可する最小バージョンと照合する形も使えます。同梱CLIの更新は、0.2.157から0.2.158のようにSDK自体の版が1つ上がる更新で起きるため、自動更新ツールが出すPRでも上がった同梱CLIの値を確認する意味があります。
まとめ
400の原因は同梱CLIの古さで、0.2.158以降のwheelなら解消しています。検知はterminal_reasonとis_errorで行い、Windowsでは_bundled/に実行ファイルがあるかまで見ます。
claude-agent-sdkの配布まわりのつまずきは、これが初めてではありません。wheelが公開されずインストールに失敗した障害はclaude-agent-sdkのwheelが公開されず、pip installに失敗する原因と対処法に、大きな応答で止まるJSONDecodeErrorは大きいメッセージでJSONDecodeErrorが発生し停止する原因と対処にあります。