If your codebase has lived through more than one Claude upgrade, you may have three different thinking parameter shapes in your git history. Each generation changed not just the parameter, but the default behavior — and each transition has specific request shapes that now return a 400 invalid_request_error. This article walks the upgrade path in order, with the exact change to make at each step.
Generation 1: extended thinking with a manual budget
The original mechanism is extended thinking: you opt in and hand the model a fixed token budget for its reasoning.
thinking={"type": "enabled", "budget_tokens": 8000}
Budget tokens are a subset of max_tokens, billed as output tokens. Among currently supported models, Claude Haiku 4.5 is the notable one that works this way — it supports extended thinking but not adaptive thinking. Claude Opus 4.6 and Sonnet 4.6 sit on the boundary: they support both extended and adaptive thinking, which makes them useful stepping stones during a migration.
Generation 2: adaptive thinking plus effort
Starting with Claude Opus 4.7 (and Sonnet 5 on the Sonnet line), the manual budget is gone. The model decides how much to think; you steer it with an effort level instead of a token count.
thinking={"type": "adaptive"},
output_config={"effort": "high"}
The 400 triggers at this step, per Anthropic's migration guide:
thinking: {"type": "enabled", "budget_tokens": N}returns 400 — replace with{"type": "adaptive"}.temperature,top_p, ortop_kat non-default values return 400 — remove them entirely.- Assistant message prefilling returns 400 — use structured outputs (
output_config.format) or system-prompt instructions instead.
Defaults also shifted within this generation. On Opus 4.7, adaptive thinking is off by default. On Opus 4.8 and Sonnet 5, it's on by default with effort defaulting to high — and Opus 4.7 → 4.8 is otherwise fully backward compatible, with effort levels recalibrated (medium thinks somewhat more, high somewhat less, xhigh substantially more). Sonnet 5 accepts thinking: {"type": "disabled"} if you want it off. One more visible change: thinking content is omitted from responses by default — opt back in with thinking: {"type": "adaptive", "display": "summarized"}.
Generation 3: always-on adaptive (Claude Fable 5)
On Claude Fable 5 (claude-fable-5), adaptive thinking is always on and no longer optional. A request with no thinking field runs with adaptive thinking; thinking: {"type": "disabled"} — legal on Sonnet 5 and Opus 4.8 — now returns an error, so the correct move is to omit the parameter. Manual extended thinking remains unsupported, effort (default high) is the depth control, and raw chain of thought is never returned; set thinking.display: "summarized" if you need summaries.
| Upgrade step | Remove / avoid (400 trigger) | Send instead |
|---|---|---|
| Opus 4.6 / Sonnet 4.6 → Opus 4.7 / Sonnet 5 | budget_tokens; non-default temperature/top_p/top_k; prefill | thinking: {"type": "adaptive"} + output_config.effort |
| Opus 4.7 → Opus 4.8 | Nothing — no breaking changes | Same shape; note recalibrated effort levels |
| Opus 4.8 → Fable 5 | thinking: {"type": "disabled"}; prefill | Omit thinking (or set adaptive + display); tune effort |
Writing upgrade-tolerant code
The safest pattern is to build the thinking configuration per model family rather than hard-coding one shape. Keep a small map from model ID to parameter shape, and treat "no thinking field at all" as the correct configuration for Fable 5 rather than an oversight. Because Opus 4.6 and Sonnet 4.6 accept both generations' shapes, they make good canary models: switch them to the adaptive shape first, verify behavior, then move the model string forward. This works identically across platforms — the parameter shapes are the same on Bedrock, Vertex AI, and Foundry — though thinking features carry beta status on Foundry, and Microsoft documents per-model thinking support explicitly (e.g. claude-fable-5 supports only adaptive).
Where to go next
For budgeting reasoning tokens on generation-1 models, see the thinking budget explainer. If you're planning the full upgrade, pair this with cache pre-warming and the tokenizer break, which land at the same time.