Why did Claude Sonnet 5.5 break an API integration that worked before?
Claude Sonnet 5.5 is not a pure model-name swap. Anthropic lists several breaking API changes for applications moving from Claude Sonnet 5 and additional cumulative changes for developers migrating directly from Sonnet 4.6, Sonnet 4.5, Haiku 4.5 or older models.
The most visible failures are concentrated around
thinking configuration and tool use.
A request that was valid on Sonnet 5 can return an
HTTP 400 error immediately after changing only
claude-sonnet-5 to
claude-sonnet-5-5.
The new model ID is
claude-sonnet-5-5. Anthropic lists a
1 million token context window, up to 128K normal
output tokens, pricing of $2 per million input
tokens and $10 per million output tokens, and
adaptive thinking enabled by default on the
Claude API.
Most common migration mistake
Changing the model ID without changing the old request settings
If the previous request explicitly disabled thinking, forced a specific tool, used a manual thinking budget, relied on non-default sampling controls or assumed the first returned content block was always text, the integration needs more than a model-name update.
Official Anthropic references: Claude Sonnet 5.5 migration guide and Claude Sonnet 5.5 model overview .
Claude Sonnet 5.5 API error matrix
| Error or symptom | Likely cause | Fix |
|---|---|---|
thinking.type.disabled not supported
|
Old Sonnet 5 no-thinking setting. |
Replace it with
thinking: {"type":"between_tools"}
at high effort or below.
|
thinking.type.enabled not supported
|
Legacy manual extended-thinking configuration
using budget_tokens.
|
Use adaptive thinking and control depth with
output_config.effort.
|
between_tools returns 400
|
Effort is xhigh or
max, or an unsupported extra
field was added.
|
Use low, medium or high effort, and send only
{"type":"between_tools"}.
|
Tool choice tool or
any rejected
|
Sonnet 5.5 does not support forced tool use. |
Use tool_choice: {"type":"auto"}
and instruct Claude when the tool must be used.
|
Code fails on content[0].text
|
The first block may now be a
thinking block.
|
Select blocks by their
type, not array position.
|
| Tool loop gets a 400 after the first call | Thinking blocks were dropped, edited or reconstructed. | Append the complete assistant content unchanged before returning tool results. |
| Agent appears silent between tool calls | Longer progress notes now arrive as thinking blocks and thinking display defaults to omitted. |
Render thinking updates where appropriate,
or use between_tools.
|
| Sampling parameter returns 400 |
Non-default temperature,
top_p or top_k.
|
Remove the non-default sampling parameter. |
| Computer tool version returns 400 |
Using computer_20251124 on
Claude API or Google Cloud.
|
Move to
computer_toolset_20260801
on those platforms.
|
Fix 1: Replace thinking.type disabled
This is the most important Sonnet 5 to Sonnet 5.5 migration change for applications that deliberately ran without thinking.
Claude Sonnet 5 accepted:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=16000,
thinking={"type": "disabled"},
output_config={"effort": "high"},
messages=[
{"role": "user", "content": "Fix this bug."}
],
)
On Sonnet 5.5,
thinking.type.disabled is no longer
accepted.
Anthropic's replacement for the old no-thinking
mode is between_tools.
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=16000,
thinking={"type": "between_tools"},
output_config={"effort": "high"},
messages=[
{"role": "user", "content": "Fix this bug."}
],
)
The wording matters. between_tools
does not mean Sonnet 5.5 can never think.
It means there is no extended thinking before the
initial answer. In an agentic workflow, Claude can
still produce progress-update thinking blocks
between tool calls.
How between_tools works, and why it can still return a 400
Anthropic describes between_tools as
the lowest thinking setting available on
Claude Sonnet 5.5. It is intended for
integrations that previously disabled thinking and
want to preserve low latency before the initial
answer.
There are three restrictions developers need to remember.
-
Effort must be high or below.
between_toolsis accepted atlow,mediumandhigh. It returns a 400 atxhighormax. -
Do not attach other thinking fields. Anthropic says
between_toolstakes nodisplay,budget_tokensorblock_bindingfield. -
Do not change effort mid-conversation. With
between_tools, a per-message effort setting that differs from the effort already in effect returns a 400 error.
This configuration fails
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=16000,
thinking={"type": "between_tools"},
output_config={"effort": "xhigh"},
messages=[
{"role": "user", "content": "Analyze this repository."}
],
)
Use adaptive thinking when you need xhigh or max
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=32000,
thinking={"type": "adaptive"},
output_config={"effort": "xhigh"},
messages=[
{"role": "user", "content": "Analyze this repository."}
],
)
You can also omit the thinking field
entirely. On Sonnet 5.5, omitting it means adaptive
thinking is on.
Use adaptive thinking for reasoning-heavy
requests without tools. Anthropic notes
that a request using between_tools
and no tools does not think before answering.
For multi-step reasoning, calculations or
analytical JSON work, adaptive thinking is the
more appropriate setting.
Anthropic documentation: Turn off up-front thinking .
Fix 2: Remove budget_tokens and manual extended thinking
Developers migrating directly from Sonnet 4.6, Sonnet 4.5 or Haiku 4.5 can encounter a different thinking error.
Older configurations could use a fixed thinking budget:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=16000,
thinking={
"type": "enabled",
"budget_tokens": 10000
},
messages=[
{"role": "user", "content": "Analyze this problem."}
],
)
Sonnet 5.5 rejects that pattern.
Replace the fixed token budget with adaptive thinking and an effort level:
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=16000,
thinking={"type": "adaptive"},
output_config={"effort": "high"},
messages=[
{"role": "user", "content": "Analyze this problem."}
],
)
There is no exact conversion such as “10,000 budget tokens equals high effort.” Anthropic explicitly recommends running evaluations at multiple effort levels instead of translating an old budget numerically.
Fix 3: Sonnet 5.5 rejects forced tool choice
This change can break an existing agent even when its thinking settings are already correct.
Sonnet 5 and earlier models allowed
tool_choice with a type of
tool or any.
Sonnet 5.5 rejects both.
Old forced-tool pattern
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=tools,
tool_choice={
"type": "tool",
"name": "get_weather"
},
messages=[
{
"role": "user",
"content": "What's the weather in Paris?"
}
],
)
Sonnet 5.5 pattern
strict_tools = [
{**tool, "strict": True}
for tool in tools
]
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
tools=strict_tools,
tool_choice={"type": "auto"},
messages=[
{
"role": "user",
"content": (
"What's the weather in Paris? "
"Use the get_weather tool."
)
}
],
)
The practical replacement is
tool_choice: {"type":"auto"}.
If calling a tool is required for the task, say so
clearly in the prompt.
Anthropic also recommends strict tool use when you
need tool arguments to conform to the declared
input schema. Strict tool schemas require
additionalProperties: false on each
object and support a subset of JSON Schema.
Amazon Bedrock exception:
Anthropic's migration guide says structured
outputs, including strict tool use, are not
available for Sonnet 5.5 on Amazon Bedrock.
There, use auto, tell Claude in the
prompt when to call the tool, and validate the
tool input in your own application.
Fix 4: Stop reading content[0].text
One of the easiest migration bugs to miss does not necessarily produce a clean Anthropic API error. Instead, the application itself can fail when it parses the response.
Sonnet 5.5 uses adaptive thinking by default.
A response can therefore begin with one or more
thinking blocks before the first
text block.
Code like this is unsafe:
text = response.content[0].text print(text)
Read blocks according to their type instead:
for block in response.content:
if block.type == "text":
print(block.text)
The same principle applies when streaming. Do not assume the first block, first event or first content delta corresponds to visible answer text.
Anthropic says thinking content is omitted by
default on Sonnet 5.5. A thinking block can
therefore contain an empty visible
thinking field while still carrying
information such as its signature that the API
needs for the conversation.
Migration rule
Treat the response as typed content blocks, not as a text array
Handle thinking,
text,
tool_use and other block types by
their declared type. This avoids response-parser
failures as the model's output structure changes.
Fix 5: Preserve thinking blocks exactly in tool-use loops
If Sonnet calls one of your client-side tools,
your application executes it and sends a
tool_result back to Claude.
With Sonnet 5.5, do not rebuild the assistant turn
by extracting only the tool_use block.
Anthropic says the thinking blocks from that
assistant response must be passed back
complete and unmodified with the
rest of the assistant turn.
Problematic approach
# Risky: drops other assistant content blocks.
messages.append({
"role": "assistant",
"content": [
tool_use_block
]
})
Preserve the entire assistant content
# Preserve every content block exactly as returned.
messages.append({
"role": "assistant",
"content": response.content
})
messages.append({
"role": "user",
"content": tool_results
})
This also makes the application more future-proof: the conversation history retains thinking, text and tool-use blocks in the ordering the API produced.
Keep the conversation append-only
Sonnet 5.5 thinking blocks are cryptographically tied to the model and the preceding conversation. Anthropic warns that editing older messages, reconstructing the system prompt or changing earlier conversation state before replaying a thinking block can invalidate it.
For accounts created on or after August 31, 2026, Anthropic says replaying such a thinking block after editing earlier history can return a 400 error by default on the Claude API, Amazon Bedrock and Google Cloud.
Keep normal message history append-only. If your application needs to change instructions during a long session, use the supported mid-conversation instruction mechanisms rather than rewriting old turns.
Official guidance: Anthropic Sonnet 5.5 migration guide and How Claude tool use works .
Why your agent may look silent between tool calls
Sonnet 5.5 changes where some user-facing progress text appears.
Anthropic says longer notes that Sonnet 5.5 writes between tool calls now come back as progress-update thinking blocks. Shorter remarks can still arrive as ordinary text blocks.
Because the default thinking display is
omitted, an interface that renders only
text blocks can appear to become quiet
during a long agentic turn even though the model is
still working.
If your product intentionally shows those progress
updates, Anthropic documents an
updates thinking display option for
adaptive thinking under its current beta header.
The simpler alternative for integrations that do
not need up-front thinking is
between_tools, whose between-tool
progress notes are returned with their summary text.
This is primarily a response-rendering change, not necessarily an API failure. If tool execution still proceeds but the user sees no progress text, inspect the returned block types before treating the agent as stalled.
Fix 6: Remove non-default temperature, top_p and top_k
Developers migrating from older Sonnet models may still have sampling controls in a shared request wrapper.
Sonnet 5.5 rejects non-default values for
temperature,
top_p and
top_k.
Remove this pattern
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=4096,
temperature=0.2,
messages=[
{"role": "user", "content": "Write the report."}
],
)
Use prompting and effort instead
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=4096,
output_config={"effort": "medium"},
messages=[
{
"role": "user",
"content": (
"Write a concise factual report. "
"Avoid speculation and keep the tone consistent."
)
}
],
)
Effort controls how deeply Sonnet reasons; it is not a direct replacement for randomness controls. Use clear prompting for style, length and output behavior.
Check max_tokens after enabling adaptive thinking
Sonnet 5.5's thinking tokens count toward
max_tokens together with the visible
response.
That matters for an application that previously ran
without thinking and sized max_tokens
close to the expected answer length. After migration,
some of that output budget can be consumed by
thinking before the visible answer is complete.
If a response unexpectedly ends with
stop_reason: "max_tokens", review both
the effort setting and the output limit rather than
assuming the model ignored the task.
Sonnet 5.5 limits
Normal maximum output: 128K tokens
Anthropic lists a 1M token context window and a
normal maximum output of 128K tokens for Sonnet
5.5. The correct production value for
max_tokens should still be based on
the workload and the amount of output cost your
application is willing to permit.
Fix 7: Update computer use on Claude API and Google Cloud
An application using Anthropic's computer-use tool can fail even when ordinary text and function tools work correctly.
On the Claude API and Google Cloud, Sonnet 5.5
supports computer use through
computer_toolset_20260801.
Anthropic says the older
computer_20251124 tool returns a
400 error there.
| Platform | Sonnet 5.5 configuration | Important note |
|---|---|---|
| Claude API |
computer_toolset_20260801
|
Older
computer_20251124
is rejected.
|
| Google Cloud |
computer_toolset_20260801
|
Same migration as the Claude API. |
| Amazon Bedrock |
computer_20251124
|
Anthropic's migration table keeps this version for Bedrock. |
If the request uses the new computer toolset,
remove the old
fine-grained-tool-streaming-2025-05-14
beta header. Anthropic says that beta header
alongside a computer-use or browser-use toolset
can itself return a 400 error. For tools that need
eager streaming, use the newer
eager_input_streaming setting described
in Anthropic's tool documentation.
What if your SDK does not recognize between_tools?
A type-checking error in your local application is different from an API-side 400.
Anthropic warns that older Python and TypeScript SDK
versions may not define the new
between_tools thinking type yet.
In that case, an IDE, TypeScript compiler or SDK
validation layer can complain before the request
even reaches Anthropic.
Update the Anthropic SDK first. If you intentionally use a lower-level request layer, Anthropic notes that the value can also be sent as raw JSON where the client permits it.
If the API request never appears in your network logs and the error is a local TypeScript or Python type error, investigate the SDK version before changing the Sonnet prompt or model configuration.
Working Python example for Sonnet 5.5 with a tool
The following pattern incorporates the main migration principles: Sonnet 5.5 model ID, adaptive thinking, effort control, automatic tool choice, block-type parsing and full assistant-turn preservation.
import json
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "get_order_status",
"description": "Look up the current status of an order.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"order_id": {
"type": "string"
}
},
"required": ["order_id"],
"additionalProperties": False
}
}
]
messages = [
{
"role": "user",
"content": (
"Check order BV-1042 with the "
"get_order_status tool and explain the result."
)
}
]
while True:
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=4096,
thinking={"type": "adaptive"},
output_config={"effort": "medium"},
tools=tools,
tool_choice={"type": "auto"},
messages=messages,
)
# Preserve the COMPLETE assistant turn.
messages.append({
"role": "assistant",
"content": response.content
})
if response.stop_reason != "tool_use":
for block in response.content:
if block.type == "text":
print(block.text)
break
tool_results = []
for block in response.content:
if block.type != "tool_use":
continue
if block.name == "get_order_status":
order_id = block.input["order_id"]
# Replace this with your real database/API lookup.
result = {
"order_id": order_id,
"status": "shipped",
"carrier": "Example Carrier"
}
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({
"role": "user",
"content": tool_results
})
Notice that the code never extracts the
tool_use block and rebuilds the
assistant response from scratch. It appends
response.content intact, preserving
any thinking blocks exactly as Anthropic returned
them.
It also reads final visible output by looking for
blocks whose type is text rather than
assuming text occupies index zero.
Working TypeScript request for Sonnet 5.5
For an ordinary request with no tool execution, the main migration point is still to read content according to block type.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 4096,
thinking: {
type: "adaptive"
},
output_config: {
effort: "medium"
},
messages: [
{
role: "user",
content: "Review this bug report and propose a fix."
}
]
});
for (const block of response.content) {
if (block.type === "text") {
console.log(block.text);
}
}
TypeScript with no up-front thinking
const response = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 4096,
thinking: {
type: "between_tools"
},
output_config: {
effort: "medium"
},
messages: [
{
role: "user",
content: "Summarize this support ticket."
}
]
});
If an installed SDK version reports that
between_tools is not a valid type,
update the SDK before assuming the Claude API itself
does not support the setting.
Anthropic also provides an automated migration command
Developers using Claude Code can ask Anthropic's bundled Claude API skill to inspect and migrate a project.
/claude-api migrate this project to claude-sonnet-5-5
According to Anthropic, the migration skill can apply the model-ID change, detect relevant breaking parameters, replace older patterns and produce a checklist of items that still need manual verification.
It also detects Amazon Bedrock and Claude Platform on AWS code paths so that platform-specific model IDs and feature differences can be handled separately.
This is useful for a larger codebase where an old
setting such as temperature,
tool_choice: "tool" or
thinking.type: "disabled" may be
buried inside a shared wrapper rather than the
file where the developer changes the model name.
A refusal is not the same as an API error
Sonnet 5.5 also introduces broader real-time safety classifiers than Sonnet 5, particularly around cybersecurity.
A safety decline can return successfully at the
HTTP layer with
stop_reason: "refusal".
That is different from a malformed request returning
HTTP 400.
Anthropic's current Sonnet 5.5 migration guide documents refusal categories including cyber, biology, frontier-model development, reasoning extraction and general harms.
Therefore, an application that treats every non-answer as a transport failure can misdiagnose a valid Sonnet 5.5 response.
if response.stop_reason == "refusal":
print("Claude declined this request.")
elif response.stop_reason == "max_tokens":
print("Output limit reached.")
elif response.stop_reason == "tool_use":
print("Claude requested a client-side tool.")
else:
for block in response.content:
if block.type == "text":
print(block.text)
Sonnet 5.5 migration checklist
If an application began failing immediately after the Sonnet 5.5 upgrade, work through the request in this order.
-
Confirm the model ID. Use
claude-sonnet-5-5on the Claude API. Other providers can have their own platform-specific identifier format. -
Search for thinking.type disabled. Replace it with
between_toolsif you need no up-front thinking, or use adaptive thinking. -
Search for thinking.type enabled and budget_tokens. Remove manual budgets and use
output_config.effort. -
Check the effort level. Do not combine
between_toolswithxhighormax. -
Remove forced tool choice. Replace
tooloranywithauto. -
Update response parsing. Select
text,thinkingandtool_useby type instead of position. -
Preserve assistant content in tool loops. Send thinking blocks back unchanged along with the tool-use blocks.
-
Keep conversation history append-only. Do not silently rewrite earlier turns before replaying signed thinking blocks.
-
Remove non-default sampling parameters. Check shared wrappers for
temperature,top_pandtop_k. -
Revisit max_tokens. Adaptive thinking consumes part of the output budget.
-
Update computer-use configuration. On Claude API and Google Cloud, use the
computer_toolset_20260801toolset. -
Update the SDK if needed. Older SDK versions may not recognize
between_tools. -
Handle refusal separately from HTTP errors. Check
stop_reasonbefore treating an empty or declined answer as an API outage.
Recommended settings for common Sonnet 5.5 workloads
| Workload | Thinking | Starting effort | Why |
|---|---|---|---|
| Fast chat |
Adaptive or
between_tools
|
Low or medium | Prioritizes latency for simpler requests. |
| Well-specified agent task | Adaptive | Medium | Anthropic recommends medium as a starting point for well-scoped agentic work. |
| Hard multistep agent | Adaptive | High | Gives the model more reasoning room for harder or longer workflows. |
| Preserve old no-thinking behavior |
between_tools
|
Low, medium or high | Removes up-front thinking while still supporting between-tool progress. |
| xhigh or max reasoning | Adaptive | Xhigh or max |
between_tools is not accepted
at these effort levels.
|
These are starting points rather than universal performance guarantees. Anthropic says Sonnet 5.5's effort levels are recalibrated relative to Sonnet 5, so production applications should run their own evaluations rather than carry an old effort choice forward blindly.
Frequently asked questions
What is the API model ID for Claude Sonnet 5.5?
Anthropic lists the Claude API model ID as
claude-sonnet-5-5. Sonnet 5.5 was
released on September 28, 2026.
Why does thinking.type disabled return a 400 error?
Sonnet 5.5 does not support
thinking: {"type":"disabled"}.
Anthropic replaced that behavior with
thinking: {"type":"between_tools"}
for integrations that need the lowest thinking
setting and no up-front thinking.
Can I use between_tools with max effort?
No. Anthropic says between_tools is
accepted at low, medium and high effort. At
xhigh or max, it returns
a 400 error. Use adaptive thinking for those
effort levels.
Why does tool_choice tool return an error?
Sonnet 5.5 does not support forced tool-choice
types tool or any.
Use tool_choice: {"type":"auto"}
and clearly instruct the model when it should
call the relevant tool.
Why is response.content[0].text failing?
Adaptive thinking can place a
thinking block before the first
text block. Iterate through response
content and select blocks according to their
type.
Do I have to send thinking blocks back after a tool call?
Yes. Anthropic says thinking blocks must be sent
back complete and unmodified with the assistant
turn when continuing a tool-use loop. The easiest
pattern is to append the entire
response.content object unchanged.
Does Sonnet 5.5 still support budget_tokens?
No. Manual extended thinking using
thinking.type: "enabled" with
budget_tokens returns a 400 error.
Use adaptive thinking and
output_config.effort.
Can I set temperature to 0 on Sonnet 5.5?
Anthropic says non-default values for
temperature, top_p or
top_k are not accepted on Sonnet
5.5 and return a 400 error. Use prompting to
steer style and behavior instead.
Why is my Sonnet 5.5 agent quiet between tool calls?
Longer progress updates can now arrive in
thinking blocks rather than ordinary
text blocks. Because thinking display is omitted
by default, an interface rendering only text may
appear silent while the agent continues working.
Is between_tools the same as completely disabling thinking?
Not exactly. It removes up-front extended thinking, but Claude can still produce progress-update thinking blocks between tool calls. On a request without tools, Anthropic says the model answers without thinking first.
The fastest way to fix a Sonnet 5.5 migration
If the application worked on Sonnet 5 and failed
immediately after switching to
claude-sonnet-5-5, start with two
searches across the codebase:
thinking and
tool_choice.
Replace the old disabled-thinking configuration
with between_tools where appropriate,
keep that mode at high effort or below, and replace
forced tool choice with auto.
Then inspect the response loop. Read blocks by type, preserve every thinking block unchanged when returning tool results, keep the conversation append-only and make sure the output budget leaves room for thinking.
Developers migrating from older Sonnet versions should also remove manual thinking budgets and non-default sampling parameters, update computer-use tool versions where applicable, and verify that the installed Anthropic SDK understands Sonnet 5.5's new settings.
Those changes address the most important breaking request and response behaviors documented by Anthropic for Sonnet 5.5.