CLAUDE LABEN
RELEASE — Claude Code v2.1.251 が8月28日に公開されました。変更点は100件近くに及び、権限とサンドボックスの締め直し、そして使用量とコストの可視化が二本柱になっていますSECURITY — Read・Write・Edit が、権限チェックの後に作業ディレクトリ内で差し替えられたシンボリックリンクを追い、承認された場所の外を読み書きできていた問題が修正されましたSECURITY — Grep と Glob が、シンボリックリンク経由の検索パスの先で Read(...) の拒否ルールを適用していませんでした。プラグインコマンドのパストラバーサルもあわせて封鎖されていますCOST — /cost にセッション単位のプロンプトキャッシュ行が入りました。ヒット率・ミス数・再キャッシュしたトークン数・warm/cold が見え、ステータスライン用の prompt_cache も追加されていますHOOKS — PreModelSwitch と PostModelSwitch が新設され、モデル切り替えをブロック・確認・注釈できます。SessionStart の resume フックは陳腐化度合いと再キャッシュ推定コストを受け取りますMODEL — Enterprise シート課金の既定モデルが Opus 5 になりました。/effort はモデルごとに既定値を保存します。週次上限50%増の延長は8月31日までで、残り1日ですRELEASE — Claude Code v2.1.251 が8月28日に公開されました。変更点は100件近くに及び、権限とサンドボックスの締め直し、そして使用量とコストの可視化が二本柱になっていますSECURITY — Read・Write・Edit が、権限チェックの後に作業ディレクトリ内で差し替えられたシンボリックリンクを追い、承認された場所の外を読み書きできていた問題が修正されましたSECURITY — Grep と Glob が、シンボリックリンク経由の検索パスの先で Read(...) の拒否ルールを適用していませんでした。プラグインコマンドのパストラバーサルもあわせて封鎖されていますCOST — /cost にセッション単位のプロンプトキャッシュ行が入りました。ヒット率・ミス数・再キャッシュしたトークン数・warm/cold が見え、ステータスライン用の prompt_cache も追加されていますHOOKS — PreModelSwitch と PostModelSwitch が新設され、モデル切り替えをブロック・確認・注釈できます。SessionStart の resume フックは陳腐化度合いと再キャッシュ推定コストを受け取りますMODEL — Enterprise シート課金の既定モデルが Opus 5 になりました。/effort はモデルごとに既定値を保存します。週次上限50%増の延長は8月31日までで、残り1日です
記事一覧/Claude Code
Claude Code/2026-08-30中級

thinking を切ったまま effort xhigh を指定した設定が、いま黙って high で走っています

thinking を無効にしたまま effort を xhigh や max にすると 400 が返ります。この失敗が黙って high に落ちる挙動へ変わったため、送信前に組み合わせを判定する小さなプリフライトを用意しました。

Claude Code240effort2thinkingOpus 5トラブルシューティング41

夜間の無人タスクが、朝には全部終わっていました。失敗ログはありません。ただ、いちばん重い工程だけ、いつもより明らかに雑な仕上がりになっています。

原因を辿ると、xhigh を指定していたはずの工程が high で走っていました。エラーは一度も出ていません。落ちてくれた方がまだ楽だった、というのが正直なところです。

この取り違えは、thinkingeffort という二つのつまみが互いに制約し合っていることを知らないと見つかりません。順に整理していきます。

is not supported when thinking is disabled が返るのは、いつか

まず、エラーとして表に出ていた頃の姿から確認します。返ってくるのは 400 で、本文はこの形です。

output_config.effort 'xhigh' is not supported when thinking is disabled

Claude Opus 5 は思考が既定でオンになっているモデルです。thinking: {"type": "disabled"} を明示して切ること自体はできますが、それが許されるのは efforthigh 以下のときに限られます。xhighmax については、思考を切った状態での実行を受け付けません。この判定はリクエストごとに行われるため、「セッションの最初だけ通っていた」という抜け道もありません。

最小の再現はこれだけです。

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 1024,
    "thinking": {"type": "disabled"},
    "output_config": {"effort": "xhigh"},
    "messages": [{"role": "user", "content": "ping"}]
  }'

efforthigh に落とすか、thinking の行を丸ごと消すか、どちらかで通ります。エラーメッセージ自体も「effort を high 以下にするか、thinking を有効にしてください」と両方の出口を示してくれます。

ここまでは、素直な仕様です。問題はこの先にあります。

モデルごとに、拒否される指定が違います

thinking は世代によって受け付ける型が入れ替わってきました。設定ファイルを使い回したままモデル名だけ差し替えると、ここで足を取られます。

モデル使える thinking の型既定400 になる指定
Claude Fable 5adaptive のみ常時オンenabled / disabled
Claude Opus 5adaptive のみオンenabled、および disabled(effort が xhigh・max のとき)
Claude Opus 4.8 / 4.7adaptive のみオフenabled
Claude Sonnet 5adaptive のみオンenabled
Claude Opus 4.6 / Sonnet 4.6adaptive と extended(非推奨)オフなし
Claude Opus 4.5 / Haiku 4.5 / Sonnet 4.5extended のみオフadaptive

読み方の勘所は二つあります。

ひとつは、thinking: {"type": "enabled", "budget_tokens": N} という旧来の書き方が 4.7 以降で拒否されることです。4.6 系では非推奨のまま通ってしまうので、「4.6 では動いていたのに」という形で表面化します。

もうひとつは逆向きで、4.5 世代は adaptive を受け付けません。新しい書き方に揃えたつもりでモデルを一段古いものへ落とすと、今度はそちらで 400 になります。

effort にも同じ種類の段差があります。xhighmax より後から入った水準なので、max は使えるのに xhigh は使えないモデルがあります。Haiku 4.5 と Sonnet 4.5 に至っては、effort パラメータ自体に対応していません。

エラーが消えたあとに残るもの

Claude Code の v2.1.251(2026年8月28日)で、この組み合わせの扱いが変わりました。思考を無効にしたまま effortxhigh または max にしていた場合、リクエストが失敗する代わりに high として送られます。

利用者としては、たしかに親切な変更です。作業の途中で 400 に叩き落とされることはなくなりました。

ただ、私はここに引っかかりました。失敗が消えたのではなく、失敗が見えなくなっただけだからです。個人開発で無人のパイプラインを毎晩回している立場からすると、落ちてくれるエラーはむしろ扱いやすい部類に入ります。落ちた工程は再実行すれば済みます。一方で「指定と違う水準で完走した」という結果は、成果物の質を眺めて初めて疑うことになります。

しかも v2.1.251 では、/effort の既定値がモデルごとに保存されるようになりました。設定が細かく効くようになったぶん、モデルを切り替えたときに以前そのモデルで選んでいた値が戻ってくる、という経路も増えています。

私は当面、重い工程の前で /effort/status を突き合わせて、いま何がセッションに載っているのかを目で確認するようにしました。原始的ですが、静かに別物へ落ちる相手には有効です。似た性質の落とし穴として、settings.json のキー名を1文字間違えても、Claude Code は何も言わずに無視します も併せて点検の対象にしています。

送る前に、組み合わせだけ判定してしまう

API を直接叩く側は、送信前に弾いてしまうのが確実です。判定に必要な情報は上の表がすべてなので、表を定数として持ち、リクエストを組み立てる直前に照合します。

#!/usr/bin/env python3
"""thinking と effort の組み合わせを、リクエストを送る前に判定する。"""
 
# thinking: 受理する type と、そのモデルの既定
THINKING = {
    "claude-fable-5":    {"accepts": {"adaptive"}, "default": "always-on"},
    "claude-mythos-5":   {"accepts": {"adaptive"}, "default": "always-on"},
    "claude-opus-5":     {"accepts": {"adaptive", "disabled"}, "default": "on"},
    "claude-opus-4-8":   {"accepts": {"adaptive", "disabled"}, "default": "off"},
    "claude-opus-4-7":   {"accepts": {"adaptive", "disabled"}, "default": "off"},
    "claude-sonnet-5":   {"accepts": {"adaptive", "disabled"}, "default": "on"},
    "claude-opus-4-6":   {"accepts": {"adaptive", "enabled", "disabled"}, "default": "off"},
    "claude-sonnet-4-6": {"accepts": {"adaptive", "enabled", "disabled"}, "default": "off"},
    "claude-opus-4-5":   {"accepts": {"enabled", "disabled"}, "default": "off"},
    "claude-haiku-4-5":  {"accepts": {"enabled", "disabled"}, "default": "off"},
    "claude-sonnet-4-5": {"accepts": {"enabled", "disabled"}, "default": "off"},
}
 
# effort: 受理する水準(表にないモデルは effort 自体が非対応)
EFFORT = {
    "claude-fable-5":    {"low", "medium", "high", "xhigh", "max"},
    "claude-mythos-5":   {"low", "medium", "high", "xhigh", "max"},
    "claude-opus-5":     {"low", "medium", "high", "xhigh", "max"},
    "claude-opus-4-8":   {"low", "medium", "high", "xhigh", "max"},
    "claude-opus-4-7":   {"low", "medium", "high", "xhigh", "max"},
    "claude-sonnet-5":   {"low", "medium", "high", "xhigh", "max"},
    "claude-opus-4-6":   {"low", "medium", "high", "max"},
    "claude-sonnet-4-6": {"low", "medium", "high", "max"},
    "claude-opus-4-5":   {"low", "medium", "high", "max"},
}
 
NO_DISABLE_AT = {"xhigh", "max"}   # ここで thinking を切れない
STRICT_MODELS = {"claude-opus-5"}  # 上の制約が効くモデル
 
 
def normalize(model: str) -> str:
    """claude-haiku-4-5-20251001 のような日付サフィックスを落とす。"""
    parts = model.split("-")
    while parts and parts[-1].isdigit() and len(parts[-1]) == 8:
        parts.pop()
    return "-".join(parts)
 
 
def preflight(model: str, thinking_type=None, effort=None):
    key = normalize(model)
    if key not in THINKING:
        return [("unknown", f"{model} は判定表にありません。表を更新してください")]
 
    findings = []
    spec = THINKING[key]
 
    if thinking_type and thinking_type not in spec["accepts"]:
        findings.append(("400", f'thinking.type "{thinking_type}" は {key} が拒否します'))
 
    if effort:
        allowed = EFFORT.get(key)
        if allowed is None:
            findings.append(("400", f"{key} は effort パラメータ自体に非対応です"))
        elif effort not in allowed:
            findings.append(("400", f'effort "{effort}" は {key} では使えません'))
        elif (key in STRICT_MODELS and effort in NO_DISABLE_AT
              and thinking_type == "disabled"):
            findings.append(("400", f'effort "{effort}" と thinking disabled は同時に指定できません'))
 
    if effort in NO_DISABLE_AT and thinking_type is None and spec["default"] == "off":
        findings.append(("warn", f"{key} は thinking 既定オフです。"
                                 f'effort "{effort}" を活かすなら adaptive を明示してください'))
 
    return findings or [("ok", "この組み合わせは受理されます")]

手元で9通りを流したときの出力がこれです。

[    400] claude-opus-5 / thinking=disabled / effort=xhigh
          -> effort "xhigh" と thinking disabled は同時に指定できません
[     ok] claude-opus-5 / thinking=disabled / effort=high
          -> この組み合わせは受理されます
[     ok] claude-opus-5 / thinking=(未指定) / effort=xhigh
          -> この組み合わせは受理されます
[   warn] claude-opus-4-7 / thinking=(未指定) / effort=xhigh
          -> claude-opus-4-7 は thinking 既定オフです。effort "xhigh" を活かすなら adaptive を明示してください
[    400] claude-sonnet-5 / thinking=enabled / effort=high
          -> thinking.type "enabled" は claude-sonnet-5 が拒否します
[     ok] claude-sonnet-4-6 / thinking=enabled / effort=medium
          -> この組み合わせは受理されます
[    400] claude-haiku-4-5-20251001 / thinking=adaptive / effort=(未指定)
          -> thinking.type "adaptive" は claude-haiku-4-5 が拒否します
[    400] claude-haiku-4-5-20251001 / thinking=enabled / effort=low
          -> claude-haiku-4-5 は effort パラメータ自体に非対応です
[    400] claude-fable-5 / thinking=disabled / effort=(未指定)
          -> thinking.type "disabled" は claude-fable-5 が拒否します

9通りのうち 400 相当が5件、警告が1件、通過が3件でした。注目していただきたいのは 4行目の warn です。これは API が拒否する組み合わせではありません。Opus 4.7 は思考が既定オフなので、xhigh だけ指定しても期待した深さにはならない、という設計上の取りこぼしです。

400 になる組み合わせと、通るけれど意図と違う組み合わせを、同じ関数で並べて出すようにしています。前者は放っておいてもいずれ気づきますが、後者は誰も教えてくれません。

normalize() を挟んでいるのは、claude-haiku-4-5-20251001 のような日付付きの ID を表のキーに寄せるためです。8桁の数字だけを末尾から落とすので、claude-opus-4-5 のようなバージョン番号は残ります。

effort を変えると、キャッシュの前置が別物になります

もうひとつ、この話には続きがあります。

thinking の設定と effort の値は、キャッシュされるプロンプトの前置に含まれます。つまり会話の途中でどちらかを変えると、それまで積み上げたプレフィックスが一致しなくなり、cache_read_input_tokens が 0 に落ちます。

400 を避けようとして「じゃあ次のリクエストから high に下げよう」と判断したときに、静かに二重のコストが発生する経路がここにあります。エラーは消え、キャッシュも消えます。

対処は単純で、会話やセッションの単位では effort を固定し、変えたいときはワークロードごと分けます。なお、既定値を明示的に書くことは省略と等価に扱われるため、"effort": "high" と書き足すだけでキャッシュが落ちることはありません。

この「どこで区切るか」の判断そのものについては、キャッシュのTTLを1時間に延ばすかは、離席の長さではなく戻る場所で決めています で、私自身の運用の切り分け方をまとめています。

今日できる確認をひとつだけ

起動スクリプト、エージェント定義、CI のジョブ定義から xhighmax を検索してください。

grep -rn 'xhigh\|"max"' --include='*.json' --include='*.md' --include='*.sh' .

拾った箇所それぞれについて、同じ場所で指定しているモデルが xhigh に対応しているか、そして思考を切っていないかを確認します。この二点が噛み合っていない設定は、いま失敗ではなく別の水準で完走しています。

私自身、無人実行の質が落ちた原因をしばらく取り違えていました。同じ回り道を短くできれば嬉しいです。お読みいただきありがとうございました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-08-25
settings.json のキー名を1文字間違えても、Claude Code は何も言わずに無視します
キー名を書き間違えた settings.json と正しい settings.json で claude doctor の出力を比べたところ、差分はゼロでした。何が検証され何が素通りするかを5通りで測り、書き間違いを自分で落とす検査を用意します。
Claude Code2026-08-16
ビルドがメモリを食い尽くしたときの止まり方は、cgroup と ulimit で別物でした
Claude Code v2.1.233 で Bash ツールに memory cgroup 対応が入りました。上限を仮想アドレス空間に置く ulimit -v と、実メモリに置く cgroup では、止まり方も、そもそも止められるかどうかも変わります。Linux 上で実際に確かめた記録です。
Claude Code2026-07-01
Claude Code をアップデートしたら hook が発火しなくなった — ハイフン入り matcher の厳密一致化(v2.1.195)
Claude Code v2.1.195 でハイフンを含む hook matcher が部分一致から厳密一致に変わり、既存の PreToolUse フックが静かに発火しなくなりました。原因の切り分けと、壊れない matcher の書き方をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →