Invalid signature in thinking block: bound to a different conversation
The error
A multi-turn request that replays earlier thinking blocks fails with a 400 naming one of them:
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".
The message sometimes ends with a sentence naming the first message that changed — the most useful part of it. A signature that is corrupted rather than mismatched fails differently: the same opening, but without the sentence about a different conversation, and the fixes below don't apply to it.
What it means
On Fable 5.1, Opus 5.5 and Sonnet 5.5, each thinking block's signature records the conversation that produced it — the system prompt, the set of tools and every earlier message. When you send the history back, the API checks that prefix is unchanged. You changed something before the block, so the block no longer belongs to the conversation you sent.
Who sees it
Enforcement is the default for accounts created on or after the enforcement date — on every platform for Fable 5.1, for new accounts on Opus 5.5, and on the Claude API and Amazon Bedrock for Sonnet 5.5. Older accounts see it only if a request opts in by setting the binding field. That is why a harness can work for its authors and fail for a customer on a newer account.
What triggers it, and what doesn't
Triggers: editing, reordering or deleting an earlier turn; injecting a reminder or status line into a
turn and removing it next request; rebuilding the system prompt or tool list mid-session; deleting a
thinking block from the middle of the history; an image URL that serves different bytes later. Safe:
appending, including appended system messages; removing thinking blocks from the front of the history;
changing parameters outside the system prompt, tools and messages, such as effort or max_tokens;
moving cache markers; server-side compaction and context editing.
Two ways out
The one-off recovery: strip every thinking and redacted-thinking block from the history and retry
once — the turn answers without that reasoning. The durable one: send the
thinking-binding-controls-2026-08-01 beta header with prefix_mismatch_behavior: "drop_block",
which drops the stale blocks and reports each in the response's input_transformations. The real fix
is an append-only history — see
making an agent loop safe for preserved thinking.
Verified 2026-09-30 against ClaudeHow facts module (src/data/facts/) — see /about/#accuracy.