cd /news/large-language-models/claude-fable-5-1-tightens-restrictio… · home topics large-language-models article
[ARTICLE · art-118400] src=platform.claude.com ↗ pub= topic=large-language-models verified=true sentiment=· neutral

Claude Fable 5.1 tightens restrictions on reusing thinking blocks

Anthropic's Claude Fable 5.1 model tightens restrictions on reusing thinking blocks, according to the company's documentation. The update affects how developers can access and reuse the model's reasoning output, with changes to the display and handling of thinking blocks in the API. This impacts developers using Claude for complex tasks like math, coding, and agentic workflows.

read38 min views1 publishedSep 2, 2026
Claude Fable 5.1 tightens restrictions on reusing thinking blocks
Image: source

MessagesThinking

Understand how Claude's thinking works: turn it on, read thinking output, steer thinking depth with effort, and use thinking with tools, caching, and streaming.

A model that answers in a single pass has to get everything right on the first try: no scratch work, no checking, no changing course halfway through. For a proof, a tricky bug, or a long agentic task, the first approach is often not the best one.

Thinking removes that constraint. When thinking is active, Claude works through the problem in its own words before answering: it restates what is being asked, tries approaches, checks intermediate results, and abandons paths that do not hold up. That reasoning arrives in thinking

content blocks ahead of the response, and Claude draws on it to produce the final answer. This is why thinking improves performance on complex tasks like math, coding, analysis, and long-running agentic work, where the quality of the answer depends on intermediate work that would otherwise be compressed into the response itself or skipped.

Thinking has a cost: the tokens Claude spends reasoning are billed as output tokens, even when the thinking text isn't returned to you, and they count toward max_tokens

alongside the response text. This page covers how thinking behaves across the API surface: turning it on, reading its output, and managing its interactions with tools, streaming, caching, and the context window.

How thinking works #

Whether Claude thinks on a given request, and how deeply, depends on your thinking configuration and the complexity of the request.

Here is what thinking looks like in a response: one or more thinking

content blocks arrive before the text

blocks. The thinking block is still generated content, like the text

block that follows it, but it is separated from the canonical response. Each thinking block also carries a signature

field, an encrypted copy of the full reasoning that you pass back unchanged in multi-turn and tool-use conversations (see Thinking encryption):

{
  "content": [
    {
      "type": "thinking",
      "thinking": "Let me break this down. The question has two parts, so I'll start with the simpler one and use its result to constrain the second...",
      "signature": "WaUjzkypQ2mUEVM36O2Txu...."
    },
    {
      "type": "text",
      "text": "Based on my analysis..."
    }
  ]
}

You don't always see this text, and what you see is never the raw chain of thought: the text in a thinking block is a summary of Claude's reasoning. The display

field on the thinking configuration controls whether that summary is returned at all: "summarized"

returns it, while "omitted"

, the default on many models, returns thinking blocks with an empty thinking

field. Either way the block is billed the same and passed back the same in multi-turn conversations. See Controlling thinking display for per-model defaults and details.

If Claude uses tools, thinking can also appear between tool calls. See Thinking with tool use. For the full response format, see the Messages API reference.

Configuring thinking #

On most models, thinking is on by default or one parameter away. Which configuration each model accepts, and what it defaults to, is listed in the per-model configuration table on the Troubleshooting page.

On Claude Opus 5, Claude Sonnet 5, Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, and Claude Mythos Preview, thinking is already on and needs no configuration. display

defaults to "omitted"

on these models, so the thinking text is hidden until you opt in. Opt in with thinking: {"type": "adaptive", "display": "summarized"}

, which is exactly the following request with the model string swapped.

On Claude Opus 4.8, Claude Opus 4.7, Claude Opus 4.6, and Claude Sonnet 4.6, thinking is off until you set thinking: {type: "adaptive"}

, which lets Claude decide when and how deeply to think based on the request. The following examples do that, set display: "summarized"

so the thinking text is visible, and use a roomy max_tokens

:

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=16000,
    thinking={"type": "adaptive", "display": "summarized"},
    messages=[
        {
            "role": "user",
            "content": "What is the greatest common divisor of 1071 and 462?",
        }
    ],
)

for block in response.content:
    if block.type == "thinking":
        print(f"\nThinking: {block.thinking}")
    elif block.type == "text":
        print(f"\nResponse: {block.text}")

Running the example prints the summarized thinking, then the answer:

Thinking: Use Euclidean algorithm.
1071 = 2*462 + 147
462 = 3*147 + 21
147 = 7*21 + 0
GCD = 21

Response: ## Finding GCD of 1071 and 462

I'll use the **Euclidean algorithm**, repeatedly dividing and taking remainders...

Thinking tokens count toward max_tokens

, so set it high enough to leave room for both the thinking and the response text. See Cost control on the steering page and Thinking and the context window.

Turning thinking off

On Claude Sonnet 5, where thinking is on by default, you can turn it off:

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=4096,
    thinking={"type": "disabled"},
    messages=[{"role": "user", "content": "Summarize this article in one sentence."}],
)

Claude Opus 5 also has thinking on by default and accepts thinking: {type: "disabled"}

at effort high

or below. At xhigh

or max

effort, thinking cannot be turned off: requests that combine thinking: {type: "disabled"}

with those effort levels return a 400 error. This restriction applies to Claude Opus 5 and later models and is enforced on each request. With thinking disabled, Claude Opus 5 can occasionally emit tool calls as plain text or include internal XML tags in its visible output. See Running with thinking disabled for prompting mitigations.

Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, and Claude Mythos Preview reject thinking: {type: "disabled"}

. Thinking can't be turned off on these models.

If your model supports only extended thinking (see the per-model configuration table), configure it with type: "enabled"

and a budget_tokens

value instead. The Extended thinking page covers that configuration. And if any thinking configuration comes back with a 400 error, Troubleshooting thinking matches each error message to its fix.

Reading thinking output #

Controlling thinking display

The display

field on the thinking configuration controls how thinking content is returned in API responses. display

works in both modes: set it alongside type: "adaptive"

or type: "enabled"

. It accepts these values:

"summarized"

: thinking blocks containsummarized thinkingtext, a readable summary of Claude's reasoning. This is the default on Claude Opus 4.6, Claude Sonnet 4.6, and earlier models."omitted"

: thinking blocks are returned with an emptythinking

field. Thesignature

field still carries the encrypted full thinking for multi-turn continuity (seeThinking encryption). This is the default on Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, Claude Opus 5, Claude Sonnet 5, Claude Opus 4.8, Claude Opus 4.7, andClaude Mythos Preview."updates"

(beta): reasoning blocks are returned with an emptythinking

field, as with"omitted"

, and the shortprogress updatessome models write between tool calls come back as readable text. Requires the beta headerthinking-display-updates-2026-08-18

.

Set display: "omitted"

when your application doesn't surface thinking content to users. The primary benefit is faster time-to-first-text-token when streaming: the server skips streaming thinking tokens entirely and delivers only the signature, so the final text response begins streaming sooner.

With display: "omitted"

, the response contains thinking

blocks with an empty thinking

field:

{
  "content": [
    {
      "type": "thinking",
      "thinking": "",
      "signature": "EosnCkYICxIMMb3LzNrMu..."
    },
    {
      "type": "text",
      "text": "The answer is 12,231."
    }
  ]
}

Keep the following in mind when working with omitted thinking:

  • You're still charged for the full thinking tokens. Omitting reduces latency, not cost.
  • If you pass thinking blocks back in multi-turn conversations, pass them unchanged. The server decrypts the signature

to reconstruct the original thinking for prompt construction (seePreserving thinking blocks). Any text you place in thethinking

field of a round-tripped omitted block is ignored. display

is invalid withthinking.type: "disabled"

(there is nothing to display).- When using thinking.type: "adaptive"

and the model skips thinking for a simple request, no thinking block is produced regardless ofdisplay

. - When streaming with display: "omitted"

, nothinking_delta

events are emitted. Withdisplay: "updates"

, onlyprogress-update blocksstreamthinking_delta

events. SeeStreaming thinkingfor the event sequence.

In the Ruby SDK, plain hashes take display:

as the examples show. The typed ThinkingConfigAdaptive

class names the parameter display_

(trailing underscore, to avoid shadowing Ruby's Kernel#display

). Either way, the wire field is still display

.

Summarized thinking

When display

is "summarized"

, the thinking text you receive is a summary of Claude's full thinking process rather than the raw chain of thought. Summarized thinking provides the full intelligence benefits of thinking while preventing misuse. No display

setting returns the raw chain of thought.

Keep the following in mind when working with summarized thinking:

  • You're charged for the full thinking tokens generated by the original request, not the summary tokens. The billed output token count does not match the count of tokens you see in the response.
  • On Claude Opus 4.6, Claude Sonnet 4.6, and earlier models, the first few lines of thinking output are more verbose, providing detailed reasoning that's particularly helpful for prompt engineering purposes. Claude Mythos Previewsummarizes from the first token, so its thinking blocks do not show this verbose preamble. - Summarization preserves the key ideas of Claude's thinking process with minimal added latency, so summaries can stream as they arrive.
  • Summarization is processed by a different model from the one you target in your requests. The thinking model does not see the summarized output.
  • As Anthropic seeks to improve the thinking feature, summarization behavior is subject to change.

To see the model's reasoning, read the thinking

blocks rather than prompting for reasoning in the response text. On Claude Fable 5.1 and Claude Fable 5, a request that attempts to elicit the model's internal reasoning as part of the response text can be refused with stop_details.category: "reasoning_extraction"

. See Refusal categories for the field reference and handling guidance.

Streaming thinking

Thinking works with streaming. Thinking blocks stream as thinking_delta

events inside content_block_delta

events, followed by a single signature_delta

event just before the block's content_block_stop

. Text blocks stream afterward as usual.

The following examples stream a response with adaptive thinking, printing thinking and text deltas as they arrive:

client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=16000,
    thinking={"type": "adaptive", "display": "summarized"},
    messages=[
        {
            "role": "user",
            "content": "What is the greatest common divisor of 1071 and 462?",
        }
    ],
) as stream:
    for event in stream:
        if event.type == "content_block_start":
            print(f"\nStarting {event.content_block.type} block...")
        elif event.type == "content_block_delta":
            if event.delta.type == "thinking_delta":
                print(event.delta.thinking, end="", flush=True)
            elif event.delta.type == "text_delta":
                print(event.delta.text, end="", flush=True)

To reassemble complete thinking blocks with their signatures after streaming, use your SDK's message-accumulation helper where one exists (for example, stream.get_final_message()

in Python or stream.finalMessage()

in TypeScript) instead of concatenating deltas yourself.

When display: "omitted"

is set, the thinking block opens, a single signature_delta

arrives, and the block closes without any thinking_delta

events. Text streaming begins immediately after:

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":"","signature":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"signature_delta","signature":"EosnCkYICxIMMb3LzNrMu..."}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"text","text":""}}

With display: "updates"

(beta), reasoning blocks stream as they do under "omitted"

. Each progress-update block streams its text as thinking_delta

events before the tool_use

block it introduces. A of several seconds before the progress-update block opens is normal:

event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"thinking","thinking":"","signature":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"thinking_delta","thinking":"Confirmed the retry path never refreshes the expired token. Editing auth.py to add the refresh call."}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"signature_delta","signature":"Es8CCkYICxIM..."}}

event: content_block_stop
data: {"type":"content_block_stop","index":1}

event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"tool_use","id":"toolu_01D7FLrfh4GYq7yT1ULFeyMV","name":"edit_file","input":{}}}

Under "updates"

, treat a block as a progress update as soon as one of its thinking_delta

events carries non-empty text.

For general streaming mechanics, see Streaming Messages.

Thinking and effort #

The thinking

parameter controls whether Claude thinks in thinking blocks before answering; the effort

parameter controls how much work Claude puts into the whole response, which in adaptive mode includes how often and how deeply it thinks. Don't pass adaptive

as an effort

value: adaptive

is a thinking mode, not an effort level.

To learn what each effort level does to thinking behavior, see the per-level thinking behavior table on the Steering thinking page. The Effort page documents the parameter itself, including which levels each model supports. On Claude Opus 4.5, the only extended-thinking-only model that supports effort, effort composes with budget_tokens

. See Budget rules and tuning.

With the two controls separated this way, pick the one that matches your goal:

Lower cost or latency on a thinking-enabled workload: lowereffort

first. It scales the whole response down, thinking included.Claude is thinking too rarely or too shallowly: raiseeffort

, or seeSteering how often Claude thinkson the steering page.You need thinking fully off: usethinking: {type: "disabled"}

on models that allow it (see theper-model configuration table).You need a hard ceiling on spend: usemax_tokens

. Effort is soft guidance.max_tokens

is a strict limit.

Thinking with tool use #

Thinking works alongside tool use, letting Claude reason through tool selection and process tool results. Two constraints apply:

Tool choice limitation (manual mode): tool use with manual extended thinking (thinking: {type: "enabled"}

) only supportstool_choice: {"type": "auto"}

(the default) ortool_choice: {"type": "none"}

. Usingtool_choice: {"type": "any"}

ortool_choice: {"type": "tool", "name": "..."}

results in an error because these options force tool use, which is incompatible with manual extended thinking. Adaptive thinking, including on models where thinking is on by default, supports forced tool use, except on Claude Fable 5.1 and Claude Mythos 5.1 (seeResponse prefill and forced tool use).Preserving thinking blocks: when you return tool results, you must pass the thinking blocks from the assistant message back to the API, complete and unmodified. SeePreserving thinking blocks.

A tool-use loop is one assistant turn. From the model's perspective, an assistant turn doesn't complete until Claude finishes its full response, which may include multiple tool calls and results. This whole sequence is a single assistant turn:

User: "What's the weather in Paris?"
Assistant: [thinking] + [tool_use: get_weather]
User: [tool_result: "20°C, sunny"]
Assistant: [text: "The weather in Paris is 20°C and sunny"]

The entire turn runs in a single thinking mode: you can't toggle thinking in the middle of a turn, including during the tool-use loop. In extended (manual) mode, the API additionally enforces that the final assistant turn of a thinking-enabled request begins with a thinking block. Adaptive mode relaxes this: no assistant turn needs to start with one.

Mid-turn conflicts degrade gracefully. If you toggle thinking mid-turn (for example, between sending a tool call and returning its result), the API doesn't error. Instead, it silently disables thinking for that request. To preserve model quality, the API may strip thinking blocks that would create an invalid turn structure, or disable thinking when the conversation history is incompatible with thinking being enabled. To confirm whether thinking was active, check for the presence of thinking

blocks in the response.

Toggle between turns, not within them. Plan your thinking strategy at the start of each turn. Complete the assistant turn, then change the thinking configuration for the next one:

User: "What's the weather?"
Assistant: [tool_use] (thinking disabled)
User: [tool_result]
Assistant: [text: "It's sunny"]
User: "What about tomorrow?"
Assistant: [thinking] + [text: "..."] (thinking enabled - new turn)

Toggling thinking modes also invalidates prompt caching. See Thinking and prompt caching.

Preserving thinking blocks

When Claude invokes a tool, it s construction of its response to await external information. When you return the tool result, Claude continues building that same response, so its earlier reasoning must still be present. Pass every thinking

block back to the API complete and unmodified, alongside the tool_use

block it accompanied. This matters for two reasons:

Reasoning continuity: the thinking blocks capture the step-by-step reasoning that led to the tool requests. Including them lets Claude continue reasoning from where it left off.Context maintenance: tool results appear as user messages in the API structure, but they're part of one continuous reasoning flow. Preserving thinking blocks maintains that flow across API calls.

In short:

Required: within a tool-use turn, pass thinking blocks back.Recommended: across turns, pass everything back.Allowed: outside tool use, omit prior turns' thinking.

You don't need to prune old thinking yourself. Pass all thinking blocks back in multi-turn conversations, and the API automatically filters them, keeps the blocks needed to preserve the model's reasoning, and bills input tokens only for the blocks actually shown to Claude. Which prior-turn blocks are kept is per-model. See Thinking block preservation by model. To override the default, use the clear_thinking_20251015 context-editing strategy.

Within the latest assistant message, the sequence of consecutive thinking

blocks must match what the model generated in the original request: you can't rearrange, edit, or partially drop them. This includes redacted_thinking blocks.

For a complete two-turn walkthrough with code in every SDK, see Thinking in tool and multi-turn workflows. It defines a tool, receives a thinking-plus-tool-use response, and echoes the assistant turn back with the tool result.

Interleaved thinking

Interleaved thinking lets Claude think between tool calls, reasoning about each tool result before acting on it. With interleaved thinking, Claude can:

  • Reason about the results of a tool call before deciding what to do next
  • Chain multiple tool calls with reasoning steps in between
  • Make more nuanced decisions based on intermediate results

With adaptive thinking, interleaved thinking is automatic on every model that supports adaptive thinking. No beta header is needed. On Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, Claude Mythos Preview, Claude Opus 5, Claude Opus 4.8, and Claude Opus 4.7, reasoning between tool calls always appears in thinking blocks. Claude Haiku 4.5 does not support interleaved thinking. On models using manual extended thinking, interleaving requires a beta header and changes how the thinking budget is counted. Interleaved thinking in manual mode covers the per-model rules and platform-specific header behavior.

With interleaved thinking, the thinking allocation can span the entire assistant turn rather than a single response. Interleaved thinking is only supported for tools used through the Messages API.

For a worked comparison showing what interleaved thinking changes in a two-tool workflow, see How interleaved thinking changes the flow.

Progress updates between tool calls

On Claude Fable 5.1, Claude Mythos 5.1, and Claude Fable 5, the model can write a progress update between tool calls. A progress update is a sentence or two on what the model just found and what it's about to do next, written for the person watching the agent rather than as reasoning. Each one comes back as its own thinking

block with its own signature

, separate from any reasoning block at the same point. It sits immediately before the tool_use

or server_tool_use

block it introduces. At most one progress update precedes each tool call, and the model can skip any of them. Progress updates aren't interleaved thinking: they appear whether or not reasoning blocks appear between tool calls, and a response can contain both.

What a progress-update block contains depends on display:

display Reasoning blocks Progress-update blocks
"omitted" (the default on these models) Empty thinking field Empty thinking field
"updates" (beta) Empty thinking field Summary text
"summarized" Summary text Summary text, not distinguishable from a reasoning block

Use display: "updates"

for an agent interface that keeps reasoning hidden and shows the user a status line at each step. Under it, any thinking

block with non-empty text is a progress update, so render those and nothing else. It's in beta and requires the beta header thinking-display-updates-2026-08-18

(on Amazon Bedrock, Google Cloud, and Microsoft Foundry, pass the beta value as described in Beta headers). Without it, the value is rejected with the same 400 invalid_request_error

as an unknown display

value.

{
  "model": "claude-fable-5-1",
  "max_tokens": 16000,
  "thinking": { "type": "adaptive", "display": "updates" },
  "tools": [
    {
      "name": "edit_file",
      "description": "Replace the contents of a file in the repository.",
      "input_schema": {
        "type": "object",
        "properties": {
          "path": { "type": "string" },
          "content": { "type": "string" }
        },
        "required": ["path", "content"]
      }
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": "The login test fails after an hour of uptime. Find out why and fix it."
    }
  ]
}

Under "updates"

, the start of the response that follows a tool_result

looks like this. The first block is reasoning and stays empty, as it would under "omitted"

. The second carries text, so it's a progress update. Under "summarized"

both blocks carry text, and under "omitted"

both are empty.

{
  "content": [
    {
      "type": "thinking",
      "thinking": "",
      "signature": "EqMBCkYICxIM..."
    },
    {
      "type": "thinking",
      "thinking": "Confirmed the retry path never refreshes the expired token. Editing auth.py to add the refresh call.",
      "signature": "Es8CCkYICxIM..."
    },
    {
      "type": "tool_use",
      "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
      "name": "edit_file",
      "input": { "path": "auth.py", "content": "..." }
    }
  ]
}

Keep the following in mind when working with progress updates:

  • Pass progress-update blocks back unchanged with the rest of the assistant turn, like any other thinking

block. - The text you receive is a summary of the progress update, normally a sentence or two. Don't rely on its length. The progress update counts toward usage.output_tokens

at its full length, not the summary's. - A progress-update block can come back with an empty thinking

field under anydisplay

value. Render nothing for an empty block. Under"updates"

it looks the same as an empty reasoning block and needs no separate handling. - When a response stops on max_tokens

,model_context_window_exceeded

, orstop_sequence

soon after a tool call or tool result, its last block can be a progress-update block standing in for the work the model hadn't finished. Under"updates"

and"summarized"

its text is exactlyThis part of the response was interrupted before it finished.

and you can show it like any other update. Under"omitted"

it's empty. To continue, pass the assistant turn back unchanged and append a newuser

message (with atool_result

for eachtool_use

block in that turn). - When streaming, expect a of several seconds before a progress-update block opens. See the"updates"

trace inStreaming thinking. - These models write fewer progress updates at higher effortand in long tool chains. If your interface depends on them, seeAsk for user-facing progress updates.

Thinking block preservation by model

Whether thinking blocks from previous assistant turns stay in context by default depends on the model:

Keep all prior turns: Claude Opus 4.5 and later Opus models, Claude Sonnet 4.6 and later Sonnet models, Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, and Claude Mythos Preview.Keep the last turn only: earlier Opus and Sonnet models, and all Haiku models through Claude Haiku 4.5. When you pass older thinking blocks back, the API strips them automatically. You don't need to remove them yourself.

Preservation brings two benefits:

Cache optimization: preserved thinking blocks enable cache hits during tool use, as they are passed back with tool results and cached incrementally across the assistant turn, resulting in token savings in multistep workflows.No intelligence impact: preserving thinking blocks has no negative effect on model performance.

The tradeoff is context usage: long conversations consume more context space on keep-all models, because retained thinking blocks count as input like any other conversation history (see Thinking and the context window). The behavior is automatic in both regimes. No code changes or beta headers are required, and you should keep passing complete, unmodified thinking blocks back as described in Preserving thinking blocks. To override the default in either direction, use thinking block clearing.

Switching models mid-conversation. Keep passing thinking blocks back unchanged when you switch models, for example after a classifier refusal fallback. A thinking block is readable only by the model that produced it or a newer one, and the API ignores or drops the blocks the target model can't read. On Claude Fable 5.1 and Claude Mythos 5.1 the direction matters: they read every earlier model's thinking blocks and no earlier model reads theirs, so switching up to them keeps the conversation's reasoning and switching down drops it (see Preserved thinking for the exact list and for how dropped blocks are billed and reported). Strip prior thinking

and redacted_thinking

blocks yourself only to save input tokens on models that ignore rather than drop them, and never when redeeming a fallback credit, which requires the body unchanged.

Preserved thinking #

Claude preserves a thinking block, keeping it usable on later turns, only under the conditions it was created in. Starting with Claude Fable 5.1 and Claude Mythos 5.1, a thinking

or redacted_thinking

block is preserved only:

For the model that produced it, or a newer one. An earlier model can't use the block, and the API drops it from that request. SeeOnly for the model that produced it, or a newer one.In the conversation that produced it (Claude Fable 5.1 only). If thesystem

prompt, thetools

, or any earlier message changes, the block is no longer valid, and the API rejects the request or drops the block. SeeOnly in the conversation that produced it.

The block's signature

records both conditions on both models. The API checks it whenever the block comes back in a later request, including a request to a different model; Claude Mythos 5.1 checks only the model condition.

Pass blocks back unchanged. Send every assistant turn exactly as you received it, thinking blocks included, and let the API decide which blocks the model can use.

Only for the model that produced it, or a newer one

This condition is one-way: Claude Fable 5.1 and Claude Mythos 5.1 read earlier models' thinking blocks, and no earlier model reads theirs.

A conversation that moves onto Claude Fable 5.1 or Claude Mythos 5.1 keeps its reasoning. The earlier model's thinking blocks stay readable, so the model thinks as usual from the first turn after the switch.A conversation that moves from them to any earlier model loses it. The earlier model can't read their blocks, the API drops them for that request, and the earlier model reasons again from the visible messages. If the conversation later returns to Claude Fable 5.1 with the same history, its own blocks are readable again.

In full, Claude Fable 5.1 and Claude Mythos 5.1 read thinking blocks produced by each other, by Claude Opus 5, Claude Fable 5, and Claude Mythos 5, and by Claude Opus 4.8 and earlier Opus models, Claude Sonnet models, and Claude Haiku 4.5. No model other than these two can read a block produced by Claude Fable 5.1 or Claude Mythos 5.1.

A block the receiving model can't read is dropped. The API removes it before the prompt reaches the model. It doesn't count toward input_tokens

and isn't billed. When you fall back from Claude Fable 5.1 to an older model mid-conversation, for example after a classifier refusal fallback, the older model reasons again from the visible conversation. With the controls beta header the drop is reported in input_transformations

as model_binding_mismatch

. Without it the drop is silent. A server-side fallback drops unreadable blocks the same way.

Only in the conversation that produced it

A thinking block from Claude Fable 5.1 is preserved only while the conversation prefix it was produced from stays unchanged. Its signature

covers the system

prompt, the tools

, and the messages that preceded the block. Claude Mythos 5.1 records the same signature

but doesn't run this check.

This check is enforced for new accounts created on or after August 31, 2026. For accounts created earlier, the API records the condition in the signature but doesn't act on a mismatch unless the request sets thinking.block_binding.prefix_mismatch_behavior, which opts into enforcement. Anthropic plans to enforce this condition for every organization on future models. If your account was created earlier, make your application compatible now: the same append-only patterns keep the

prompt cachewarm, and you can test against the check by sending

prefix_mismatch_behavior: "error"

. If you ship a tool or framework that people run with their own API key, test that way: your users on new accounts are enforced before you are. Preserved thinkinghas the integration checklist: how to tell whether your code edits history, and the API feature that replaces each kind of edit.

Where the check is enforced, a request that replays a block against a changed prefix is rejected with a 400 invalid_request_error

:

messages.5.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block". That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.

The last sentence appears only when the request didn't send the beta header. The message can end with one more sentence naming the first message that changed. Retrying the same request body fails the same way. To continue without the invalidated reasoning instead, send the thinking-binding-controls-2026-08-01

beta header and set prefix_mismatch_behavior

to "drop_block"

. The API then drops the failing block and every thinking block after it in the conversation, and reports each one in input_transformations

as prefix_binding_mismatch

. The token counting endpoint runs the same check and returns the same 400.

What invalidates later thinking blocks:

  • Editing, reordering, or removing an earlier message, including removing a per-turn reminder you injected into an earlier user turn.
  • Changing the content of the top-level system

prompt, or adding, removing, or editing a tool in thetools

array, between requests. - Client-side compaction or truncation that keeps recent assistant turns verbatim, thinking included, while rewriting the turns before them.

  • An image or document URL in an earlier turn that serves different bytes on a later request. The check covers the bytes, not the URL string, so a rotating signed URL for the same file is fine. For content you reference across turns, upload it once with the Files APIand send thefile_id

, or send base64.

What doesn't:

  • Removing a leading run of thinking blocks, oldest first: the first thinking block in the conversation (or the first one after the most recent compaction block), then the next, and so on. Removing a thinking block from anywhere else invalidates every thinking block after it, in that turn and in every later turn.
  • Changing output_config.effort

,max_tokens

, or other sampling settings between requests. cache_control

markers, wherever you place or move them.- Server-side compactionandcontext editing: they don't count as edits, because the check compares the conversation as you sent it, not the server's edited copy. After a compaction, the checked prefix starts from the compaction block.

Patterns that keep thinking blocks valid:

Append only. Add new messages at the end ofmessages

and leave earlier turns byte-for-byte unchanged.Use and mid-conversation tool changes to add instructions or change tool availability partway through, instead of editing the top-levelmid-conversation system messagessystem

field ortools

array. For a reminder that should apply to one turn only, send it as aturn-scoped system messageand leave it in the history rather than deleting it later. This also preserves the prompt cache.Use server-side context management rather than trimming history yourself.If a request is rejected for a prefix mismatch and you can't repair the history, resend it with the beta header andprefix_mismatch_behavior: "drop_block"

, or strip everythinking

andredacted_thinking

block from the history and retry once.

When earlier thinking is dropped, the model answers that turn without those blocks. A client that repeatedly invalidates its own history restarts the prompt cache each time, which raises cost.

Client-side compaction. This check doesn't rule out compacting on the client. The rule is narrower: don't keep a thinking block behind a prefix you've rewritten. Server-side compaction is the simplest way to satisfy it. If you compact on the client, use one of these shapes:

Simple compaction (recommended): summarize the conversation into one message and start the next request with that summary plus the new user turn, replaying no earlier turns and no earlier thinking blocks. No earlier thinking remains, so nothing fails, and the model thinks afresh on the compacted conversation. Claude models are trained on long-horizon tasks with this scheme, and it performs comparably to more elaborate ones for most workloads. It resets the prompt cache, as any compaction does.Keep-tail compaction: summarize older turns and keep the most recent turns verbatim. The kept turns' thinking blocks were produced against the full history and fail behind the summary. Stripthinking

andredacted_thinking

from every turn you carry across (their text and tool calls can stay), or setprefix_mismatch_behavior: "drop_block"

and let the API discard them.Background compaction: build the summary off the critical path and swap it in while the conversation continues. Every turn produced in the meantime has thinking that predates the swap. Send"drop_block"

on every request that still carries thinking blocks produced before the swap (or strip those blocks yourself;input_transformations

on the first response after the swap lists exactly which ones), or compact synchronously.

Snipping individual turns out of the middle of the transcript invalidates every thinking block after them, and no client-side shape avoids that. Use a mid-conversation system message for the instruction change you were making, or server-side context editing for selective removal.

Controls for blocks that aren't preserved (beta)

Send the beta header thinking-binding-controls-2026-08-01

to get two things: an input_transformations

array on every response that lists any thinking blocks the API dropped, and a block_binding

object on the thinking configuration with one field.

Field Type Default Description
prefix_mismatch_behavior "error" or "drop_block" "error" What the API does with a thinking block that fails the
"error" rejects the request with a 400 error. "drop_block" removes the block and every later thinking block in the conversation, reports each in input_transformations , and continues. Neither value changes the model check, which always drops.

block_binding

is accepted alongside thinking.type: "adaptive"

and thinking.type: "enabled"

. Sending it without the beta header returns a 400 error. Models that don't run the conversation check accept the object and report only model-check drops, so one request body works across models. On Amazon Bedrock and Google Cloud, pass beta names as described in Beta headers.

The following request opts into dropping rather than rejecting. On a first turn there is nothing to replay, so input_transformations

comes back empty:

client = anthropic.Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5-1",
    max_tokens=16000,
    thinking={
        "type": "adaptive",
        "block_binding": {"prefix_mismatch_behavior": "drop_block"},
    },
    messages=[
        {
            "role": "user",
            "content": "What is the greatest common divisor of 1071 and 462?",
        }
    ],
    betas=["thinking-binding-controls-2026-08-01"],
)

for block in response.content:
    if block.type == "text":
        print(block.text)

print(f"Input transformations: {len(response.input_transformations or [])}")
The greatest common divisor of 1071 and 462 is 21.
Input transformations: 0

Dropped blocks are reported in input_transformations. Under the beta header, every response from a thinking-capable model carries this top-level array. It's empty when nothing was dropped and never

null

. Each entry names the position of a dropped block and the check it failed:

{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.1.content.0",
      "reason": "model_binding_mismatch"
    }
  ]
}

The reason

field is model_binding_mismatch

or prefix_binding_mismatch

. Ignore entries whose type

or reason

you don't recognize, because later checks add values. When streaming, input_transformations

arrives on the message

object in the message_start

event. After a mid-stream server-side fallback, the final message_delta

event carries the array again with the serving model's entries. Without the beta header the field is absent.

A tampered or undecryptable signature is a different failure: it always returns a 400 (Invalid signatureinthinking block

, with no reason clause) and prefix_mismatch_behavior

doesn't apply to it. In a message batch, an item whose block fails the conversation check under "error"

resolves as errored

.

Thinking and prompt caching #

Prompt caching interacts with thinking in a few specific ways. The following rules apply in both thinking modes.

Configuration changes invalidate caching. The thinking configuration and the resolved effort level are rendered into the prompt itself, so changing any of them starts a new cache prefix. Switching between

adaptive

, enabled

, and disabled

, changing budget_tokens

, and changing the effort value all invalidate cache breakpoints: message-level breakpoints always miss, and tool and system-prompt breakpoints can miss too, depending on where the model renders the configuration. Treat any thinking or top-level effort change as starting the cache over. On models that support per-message effort, an effort change carried in a

role: "system"

message inside messages

leaves the cached prefix intact. Consecutive requests that keep the same configuration preserve the cache, and setting a parameter explicitly to its default value is equivalent to omitting it. A thinking block the API drops under either preserved-thinking conditionchanges the cached prefix from that block's position onward. Blocks passed back unchanged keep the cache intact. A worked demonstration with usage output is on the

Steering thinkingpage.

Thinking blocks are cached with tool results. During a tool-use loop, caching occurs when you make a follow-up request that includes tool results. At that point the previous conversation history, including its thinking blocks, can be cached, and those cached thinking blocks count as input tokens in your usage metrics when read from the cache. This occurs automatically, even without explicit cache_control

markers, and behaves the same for regular and interleaved thinking. The tradeoff: thinking blocks you never see again in responses still contribute to input token usage when read from cache.

Whether prior blocks are in context at all is per-model. The preservation default governs this. On keep-all models, previous turns' thinking blocks stay cached and in context. On last-turn-only models, once you send a user message that isn't a tool result, all previous thinking blocks are stripped from context. On those models, a conversation like this:

User: ["What's the weather in Paris?"],
Assistant: [thinking_block_1] + [tool_use block 1],
User: [tool_result_1, cache=True],
Assistant: [thinking_block_2] + [text block 2],
User: [Text response, cache=True]

is processed as if the thinking blocks were never there:

User: ["What's the weather in Paris?"],
Assistant: [tool_use block 1],
User: [tool_result_1, cache=True],
Assistant: [text block 2],
User: [Text response, cache=True]

On keep-all models, the same request keeps thinking_block_1

and thinking_block_2

in context and in the cache.

Degradation strips thinking from the cacheable history. If thinking becomes disabled mid-turn and you pass thinking content in the current tool-use turn, the thinking content is stripped and thinking remains disabled for that request (see graceful degradation). Interleaved thinking amplifies cache invalidation effects, because thinking blocks can occur between multiple tool calls.

Thinking and the context window #

max_tokens

, which includes all thinking Claude generates in the current turn, is enforced as a strict limit. On Claude 4.5 models and newer, if input tokens plus max_tokens

exceeds the context window size, the API accepts the request. If generation then reaches the context window limit, it stops with stop_reason: "model_context_window_exceeded"

instead of returning an error. On earlier models, the API returns a validation error instead. See Handling stop reasons.

How thinking counts against the window depends on when it was generated:

Current-turn thinking always counts towardmax_tokens

, is billed as output tokens, and occupies context window space for the turn that generated it.Prior-turn thinking depends on thepreservation default. Onmodels that keep all prior turns, previous thinking blocks remain in context, count toward the window, and are billed as input tokens like the rest of the conversation history. On models that keep only the last turn, the API strips older thinking blocks automatically when you pass them back, so they don't consume window space or input tokens.

In practice:

  • On keep-all models, budget your context window as if thinking were ordinary conversation history, because it is. Long agentic sessions accumulate thinking in context. Use thinking block clearingif you need to reclaim space. - On last-turn-only models, thinking is a per-turn cost only: each turn's thinking counts against that turn's max_tokens

and then drops out of the window.

The following diagrams illustrate the last-turn-only (stripping) regime. The first shows a multi-turn conversation: each turn's thinking block is generated in the output but not carried into later turns' input.

The second shows the same regime with tool use: thinking stays in context alongside its tool result for the duration of the assistant turn, then drops out on the next user turn.

Use the token counting API to get accurate counts for your specific use case, especially for multi-turn conversations that include thinking.

Thinking encryption #

Full thinking content is encrypted and returned in the signature

field on each thinking block. The API uses the signature to verify that thinking blocks were generated by Claude when you pass them back.

Keep the following in mind when working with signatures:

  • It is only strictly necessary to send back thinking blocks when using tools with thinking. Otherwise you can omit thinking blocks from previous turns. If you do pass them back, whether the API keeps or strips them depends on the model (seeThinking block preservation by model). Usecontext editingto configure this. - When sending back thinking blocks, pass everything back exactly as you received it, for consistency and to avoid potential issues.
  • When streaming responses, the signature arrives as asignature_delta

inside acontent_block_delta

event just before thecontent_block_stop

event. signature

values are significantly longer in Claude 4 and later models than in previous models.- The signature

field is opaque: don't interpret or parse it. signature

values are compatible across platforms (the Claude API,Amazon Bedrock, andGoogle Cloud). Values generated on one platform work on another.

Redacted thinking blocks #

In addition to regular thinking

blocks, the API may return redacted_thinking

blocks when portions of Claude's reasoning are safety-redacted. A redacted_thinking

block contains encrypted thinking content in a data

field, with no readable text:

{
  "type": "redacted_thinking",
  "data": "..."
}

The data

field is opaque and encrypted. Like the signature

field on regular thinking blocks, pass redacted_thinking

blocks back to the API unchanged when continuing a multi-turn conversation with tools.

Limits and feature compatibility #

Sampling parameters

On Claude Fable 5.1, Claude Mythos 5.1, Claude Fable 5, Claude Mythos 5, Claude Mythos Preview, Claude Opus 5, Claude Opus 4.8, Claude Opus 4.7, and Claude Sonnet 5, non-default temperature

, top_p

, or top_k

values return a 400 error on every request, regardless of whether thinking is used. On older models, the restriction applies only while thinking is on: temperature

and top_k

are incompatible with thinking, and top_p

is allowed at values between 0.95 and 1.

Response prefill and forced tool use

You can't prefill the assistant response while thinking is on. Forced tool use (tool_choice: {"type": "any"}

or {"type": "tool", ...}

) is incompatible with manual extended thinking but works with adaptive thinking. The exceptions are Claude Fable 5.1 and Claude Mythos 5.1, which reject forced tool use on every request with a 400 error. On those models, use tool_choice: {"type": "auto"}

with strict tool use or structured outputs instead. See Thinking with tool use.

Output limits

Each model accepts max_tokens

up to the ceiling listed here. On the Message Batches API, the output-300k-2026-03-24

beta header raises that ceiling for the models with a batches ceiling listed.

Model Max output tokens Batches beta ceiling
Claude Fable 5.1 128k
Claude Mythos 5.1 128k
Claude Fable 5 128k
Claude Mythos 5 128k
Claude Mythos Preview 128k Not available
Claude Opus 5 128k 300k
Claude Opus 4.8 128k 300k
Claude Opus 4.7 128k 300k
Claude Sonnet 5 128k 300k
Claude Opus 4.6 128k 300k
Claude Sonnet 4.6 128k 300k
Claude Haiku 4.5 64k Not available
Claude Sonnet 4.5 64k Not available
Claude Opus 4.5 64k Not available

See the models overview for limits on legacy models.

Long requests

The SDKs require streaming when max_tokens

is greater than 21,333, to avoid HTTP timeouts on long-running requests. This is a client-side validation, not an API restriction. If you don't need to process events incrementally, use .stream()

with .get_final_message()

(Python) or .finalMessage()

(TypeScript) to get the complete Message

object without handling individual events. See Streaming Messages. Expect longer response times when thinking is active, because generating thinking blocks adds processing time. For workloads that push thinking above roughly 32k tokens per request, use batch processing to avoid networking issues: such requests can run long enough to hit system timeouts and open connection limits.

Next steps #

Steer how often and how deeply Claude thinks with effort levels, system prompt guidance, and per-message steering, and understand thinking's cost and pricing.

Walk through a complete two-turn tool-use round trip that preserves thinking blocks correctly, and see how interleaved thinking changes the flow.

Find out whether your Messages API integration edits conversation history, and replace each edit with the API feature that keeps earlier thinking blocks valid.

Diagnose and fix the most common thinking failures: configuration 400 errors, empty or missing thinking blocks, max_tokens stops, and cache misses.

Control how many tokens Claude uses when responding with the effort parameter, trading off between response thoroughness and token efficiency.

Was this page helpful?

── more in #large-language-models 4 stories · sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/claude-fable-5-1-tig…] indexed:0 read:38min 2026-09-02 ·