Torna alle guide
Risoluzione dei problemi·23 settembre 2026·6 min di lettura

API Claude 400 “Invalid `signature` in `thinking` block” — cosa ha danneggiato la firma e come recuperare

L'API ha verificato la firma di un blocco thinking che hai reinviato, ma la verifica non è riuscita: la firma è stata troncata, alterata o reinviata vuota, oppure il blocco non è mai stato firmato da Claude — o, con Claude Fable 5.1 e Claude Opus 5.5, qualcosa di precedente nella conversazione è cambiato. Reinviare la stessa cronologia fallisce ogni volta nello stesso modo. Trova cosa l'ha danneggiata, quindi rimuovi una volta sola i blocchi thinking da quella conversazione e continua — perdi il ragionamento precedente del modello, non la conversazione.

Ultima revisione: .

L'API ha verificato la firma di un blocco thinking che hai reinviato, ma la verifica non è riuscita: la firma è stata troncata, alterata o reinviata vuota, oppure il blocco non è mai stato firmato da Claude — o, con Claude Fable 5.1 e Claude Opus 5.5, qualcosa di precedente nella conversazione è cambiato. Reinviare la stessa cronologia fallisce ogni volta nello stesso modo. Trova cosa l'ha danneggiata, quindi rimuovi una volta sola i blocchi thinking da quella conversazione e continua — perdi il ragionamento precedente del modello, non la conversazione.

L’errore

risposta (HTTP 400)
// Through Kunavo: the upstream message as it reaches you, typed as Anthropic
// types a 400; no request_id field, the upstream's own id is appended instead:
{"type":"error","error":{"type":"invalid_request_error","message":"messages.1.content.0: Invalid `signature` in `thinking` block (request id: …)"}}
// (the message path, any masking of it and the appended request id vary by upstream)

// From Anthropic's API directly:
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "messages.1.content.0: Invalid `signature` in `thinking` block"
  },
  "request_id": "req_011C..."
}

// messages.{i}.content.{j}: i = position in messages[], j = block index. Both vary.
// An upstream can mask that path (***.***) and append its own request id, as above.
// Claude Code prints the body after "API Error: 400".
// On Claude Fable 5.1 and Claude Opus 5.5 the message can continue:
//   "... The block is bound to a different conversation. Remove the block, or set
//    `thinking.block_binding.prefix_mismatch_behavior` to "drop_block"."

Cause e soluzioni in breve

CausaSoluzione
La firma è stata troncata, svuotata o modificata prima di essere reinviataArchivia e riproduci ogni blocco esattamente come è stato restituito. Lascia che l'SDK assembli i turni trasmessi in streaming, così signature_delta non va perso.
Il blocco non è mai stato firmato da ClaudeUn modello non-Claude dietro un URL compatibile con Anthropic, oppure un proxy che genera le proprie firme. Reinvia quei turni solo come testo e tool_use.
Hai cambiato URL di base, account o accesso durante la conversazioneClaude Code 2.1.152+ rimuove le firme obsolete dopo il cambio di modello o di accesso. Nel tuo codice, rimuovi una volta i blocchi thinking se la prima richiesta dopo un cambio fallisce.
“Il blocco è associato a una conversazione diversa” (Fable 5.1, Opus 5.5)Il prompt di sistema, gli strumenti o un messaggio precedente sono cambiati. Mantieni la cronologia in modalità append-only, oppure attiva drop_block (richiede un'intestazione beta).
Un proxy o un gateway riscrive la cronologia durante il passaggioLe sue riscritture vengono considerate tue modifiche. Riproduci la richiesta direttamente sull'API per stabilire se è la causa.

Leggi quale verifica è fallita

La formulazione lo indica. Un messaggio che si ferma a “Invalid `signature` in `thinking` block” significa che la firma stessa non è stata verificata: Anthropic elenca come cause una firma troncata, alterata o reinviata vuota (https://platform.claude.com/docs/en/build-with-claude/thinking-troubleshooting, aggiornato a settembre 2026), e la pagina sul thinking preservato parla di una firma manomessa o non decifrabile che restituisce sempre un errore 400. Un percorso mascherato come ***.***.content.0 o un ID richiesta aggiunto da un gateway non cambia questo; ciò che conta è se segue una frase sulla conversazione. Su Claude Fable 5.1 e Claude Opus 5.5 le stesse parole possono continuare con “The block is bound to a different conversation” — si tratta di una verifica diversa, descritta nell'ultimo passaggio. Un terzo messaggio, “blocks in the latest assistant message cannot be modified”, significa che il turno assistant più recente è stato modificato, filtrato, riordinato o ricostruito; il testo thinking modificato produce questo errore, non un errore di firma. Ritentare con lo stesso corpo non risolve nessuno dei due problemi.

three thinking-block 400s
Invalid `signature` in `thinking` block
  -> the signature did not verify: truncated, altered, empty, or not Claude's

Invalid `signature` in `thinking` block. The block is bound to a different conversation. ...
  -> Fable 5.1 / Opus 5.5: system, tools or an earlier message changed after the block was made

`thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified
  -> the newest assistant turn was edited, filtered, reordered or rebuilt before it was sent back

Reinvia i turni assistant esattamente come sono stati restituiti

Ogni blocco thinking contiene una firma — una copia crittografata dell'intero ragionamento — e l'API la usa per verificare che il blocco sia stato generato da Claude (https://platform.claude.com/docs/en/build-with-claude/thinking#thinking-encryption). Aggiungi l'elenco content della risposta senza modificarlo: blocchi thinking, redacted_thinking e tool_use, inclusi i blocchi thinking il cui testo è vuoto, impostazione di visualizzazione predefinita nei modelli più recenti. Durante lo streaming, la firma arriva in un unico signature_delta subito prima della chiusura del blocco; un accumulatore scritto manualmente che lo perde archivia una firma vuota, e un blocco reinviato con una firma vuota fallisce. Il consiglio di Anthropic è lasciare che sia l'SDK ad assemblare il messaggio. L'ordine delle chiavi JSON e gli spazi bianchi non contano — contano i valori.

replay_verbatim.py
import anthropic

client = anthropic.Anthropic(base_url="https://api.kunavo.com", api_key="sk-kn-...")

tools = [{
    "name": "get_weather",
    "description": "Current weather for a city.",
    "input_schema": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
    },
}]
messages = [{"role": "user", "content": "What's the weather in Paris?"}]

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=16000,
    thinking={"type": "adaptive"},
    tools=tools,
    messages=messages,
) as stream:
    final = stream.get_final_message()   # signature_delta already applied

# Append the content list untouched: thinking, redacted_thinking, tool_use.
messages.append({"role": "assistant", "content": final.content})

# Not this: a store that keeps the text but not the signature replays
# {"type": "thinking", "thinking": "...", "signature": ""}  -> this 400.

Mantieni il thinking degli altri backend fuori dalla cronologia di Claude

Secondo la documentazione di Anthropic, il passaggio da un modello Claude a un altro sulla sua API non dovrebbe causare questo errore: invita a continuare a inviare i blocchi durante il cambio, elimina senza errore quelli che il nuovo modello non può leggere e documenta le firme come portabili tra Claude API, Amazon Bedrock e Google Cloud (https://platform.claude.com/docs/en/build-with-claude/thinking, aggiornato a settembre 2026). Ciò che non può verificare è un blocco mai firmato da Claude. Le segnalazioni pubbliche riguardano cronologie passate da un altro backend: una sessione Claude Code eseguita su un backend GLM e poi tornata ad Anthropic (github.com/anthropics/claude-code/issues/21726), turni Gemini trasformati da un proxy in blocchi thinking di Claude con firme proprie (github.com/router-for-me/CLIProxyAPI/issues/1584), una sessione Claude Code passata a un'altra chiave a metà e poi tornata indietro (github.com/lbjlaq/Antigravity-Manager/issues/388). Per i turni prodotti da un modello non-Claude, il consiglio di Anthropic è reinviare l'output di quel modello solo come contenuto text e tool_use.

foreign_turn.py
def as_foreign_turn(content: list[dict]) -> list[dict]:
    """A turn a non-Claude model produced: keep what it said and did,
    never its thinking blocks, which Claude cannot verify."""
    return [b for b in content if b["type"] in ("text", "tool_use")]

Recupera una conversazione che già fallisce

Rimuovi una volta dalla cronologia archiviata i blocchi thinking e redacted_thinking — rimuoverli tutti è la soluzione più semplice; per la variante “associato a una conversazione diversa”, il minimo indicato da Anthropic è il blocco nominato e tutti quelli successivi — mantieni ogni altro blocco nella sua posizione, salva la cronologia e continua. Anthropic indica questa procedura come recupero per una sessione salvata che non può più essere riprodotta (https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#faq); quando una firma non viene verificata, l'unica altra via d'uscita è riprodurre il blocco esattamente come è stato restituito, se lo possiedi ancora. Claude Code rimuove autonomamente il thinking precedente quando l'API rifiuta una firma. Dopo aver rimosso i blocchi e proseguito, non reinserirli: su Fable 5.1, un blocco rimosso e poi reinserito invalida il thinking prodotto mentre era assente. Il modello risponde senza il ragionamento precedente, e da quel punto il nuovo thinking è valido. In Claude Code, la versione 2.1.152 (27 maggio 2026, https://code.claude.com/docs/en/changelog) rimuove le firme obsolete dopo un cambio di modello o di accesso, e la guida del suo gateway indica che ritenta un rifiuto della firma senza i blocchi thinking precedenti — ma il tentativo riconosce il testo dell'errore upstream, e un gateway che avvolge gli errori in un proprio envelope può impedirlo (https://code.claude.com/docs/en/llm-gateway-protocol#automatic-retry-and-error-forwarding).

strip_thinking.py
THINKING = {"thinking", "redacted_thinking"}

def block_type(b) -> str:
    return b["type"] if isinstance(b, dict) else b.type   # dicts or SDK objects

def strip_thinking(messages: list[dict]) -> list[dict]:
    """One-time recovery: drop every thinking block, keep everything else."""
    out = []
    for m in messages:
        content = m["content"]
        if m["role"] == "assistant" and isinstance(content, list):
            kept = [b for b in content if block_type(b) not in THINKING]
            content = kept or [{"type": "text", "text": "(no visible reply)"}]  # keep the turn non-empty
        out.append({**m, "content": content})
    return out

messages = strip_thinking(messages)   # save this version; never re-add the blocks

Su Fable 5.1, mantieni fisso il prefisso — oppure attiva drop_block

“Associato a una conversazione diversa” è la verifica del thinking preservato: su Claude Fable 5.1 e Claude Opus 5.5, un blocco riprodotto è valido solo finché il prompt di sistema, gli strumenti e ogni messaggio precedente rimangono invariati. Anthropic lo applica per impostazione predefinita agli account creati il 31 agosto 2026 o successivamente (https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#enforcement); dietro un gateway quell'account non è tuo, quindi presumi che sia attivo. Mantieni fissi sistema e strumenti per la sessione e aggiungi contenuti invece di modificare. Per fare in modo che le richieste continuino ad avere successo mentre individui la modifica, invia l'intestazione beta thinking-binding-controls-2026-08-01 con prefix_mismatch_behavior impostato su drop_block; senza questa intestazione il campo stesso viene rifiutato con “block_binding: Extra inputs are not permitted” (https://platform.claude.com/docs/en/api/errors).

drop_block.sh
# Anthropic's API directly. The field needs the beta header; Kunavo forwards it (see below).
curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-fable-5-1",
    "max_tokens": 16000,
    "thinking": {
      "type": "adaptive",
      "block_binding": {"prefix_mismatch_behavior": "drop_block"}
    },
    "messages": [{"role": "user", "content": "..."}]
  }'

Se chiami tramite Kunavo

Kunavo inoltra i blocchi thinking e redacted_thinking tramite /v1/messages così come sono stati inviati, inclusi firma e dati — le uniche modifiche alla richiesta sono l'ID del modello e, sui modelli che li rifiutano, la rimozione di temperature, top_p e top_k — e restituisce il corpo della risposta, in streaming o meno, così come è stato inviato dall'upstream. A settembre 2026 ogni modello Claude viene servito tramite un unico canale upstream senza fallback, quindi il routing di Kunavo non sposta una conversazione tra provider e un 400 non viene mai ritentato altrove. Non abbiamo testato lo spostamento di una conversazione tra Anthropic diretto e Kunavo, quindi prevedi che la prima richiesta dopo tale cambio debba avere il thinking rimosso. Dal 24 settembre 2026 Kunavo inoltra la beta thinking-binding-controls-2026-08-01; in un test svolto quel giorno, il canale che serviva Claude ha accettato block_binding su Claude Fable 5.1 con o senza l'intestazione e non abbiamo osservato la rimozione di alcun blocco. Il rifiuto arriva come HTTP 400 di tipo invalid_request_error, senza un campo request_id, e contiene il testo del messaggio upstream — che può mascherare il percorso messages.N e terminare con l'ID richiesta dell'upstream — quindi cerca lo stato e le parole “Invalid `signature` in `thinking` block”. La rimozione e il nuovo tentativo automatici di Claude Code si basano su quella formulazione: Claude Code 2.1.280, indirizzato a un server di test che rispondeva con questo envelope, ha rimosso i blocchi thinking e ritentato. Non abbiamo attivato l'errore tramite Kunavo, quindi se una sessione continua a fallire a ogni turno, iniziane una nuova. Le richieste fallite non vengono addebitate. Ciò che l'endpoint nativo inoltra senza modifiche è elencato in riferimento all'API Messages.

Domande frequenti

Che cosa significa “Invalid `signature` in `thinking` block”?

L'API non ha potuto verificare un blocco thinking che hai reinviato. Ogni blocco thinking contiene una firma — una copia crittografata del ragionamento di Claude — e la verifica fallisce quando la firma è stata troncata, alterata o reinviata vuota, oppure quando il blocco non è mai stato firmato da Claude. È un errore 400, non transitorio: la stessa richiesta fallisce ogni volta.

Le firme dei blocchi thinking scadono?

La documentazione di Anthropic non menziona una scadenza. Nel tracker anthropic-sdk-python (issue #1598, agosto 2026), una risposta di un account che GitHub identifica come collaboratore afferma che non scadono e che la verifica fallisce quando il blocco che raggiunge l'API è diverso da quello restituito — si tratta del commento a un issue, non della documentazione. Se una sessione salvata che prima funzionava ora fallisce, verifica cosa potrebbe aver modificato i blocchi archiviati o il percorso che hanno seguito: il tuo livello di archiviazione, un proxy o un cambio di backend.

Posso semplicemente eliminare i blocchi thinking e continuare?

Sì. Anthropic lo indica come recupero per una sessione salvata che non può essere riprodotta, e Claude Code rimuove autonomamente il thinking precedente quando una firma viene rifiutata. Rimuovi i blocchi thinking e redacted_thinking — rimuoverli tutti è la soluzione più semplice — mantieni gli altri blocchi e ritenta una volta. Il modello perde il ragionamento precedente, non la conversazione; al di fuori dell'uso degli strumenti, la documentazione di Anthropic consente comunque di omettere il thinking dei turni precedenti.

Perché succede dopo il cambio di modello o provider?

La documentazione di Anthropic afferma che il passaggio tra modelli Claude sulla sua API rimuove senza errori i blocchi che il nuovo modello non può leggere e che le firme funzionano tra Claude API, Amazon Bedrock e Google Cloud. Claude Code ha comunque dovuto correggere sessioni bloccate da firme obsolete dopo un cambio di modello o di accesso (2.1.152), e le segnalazioni pubbliche riguardano cronologie passate da qualcosa che Claude non può verificare — un modello non-Claude dietro lo stesso URL di base, un proxy che genera le proprie firme o un client che le ha perse. Rimuovi una volta i blocchi thinking dopo il cambio.

Claude Code risolve automaticamente il problema?

Le versioni recenti ci provano. Dalla versione 2.1.152 rimuove le firme obsolete dopo un cambio di modello o di accesso e ritenta un rifiuto della firma senza i blocchi thinking precedenti. Il tentativo riconosce il testo dell'errore upstream, e la guida del gateway di Anthropic afferma che un gateway che avvolge gli errori in un proprio envelope può impedirlo. Esegui prima claude update; se una sessione continua a fallire a ogni turno, iniziane una nuova.

Guide correlate

Ulteriori dettagli sul significato degli errori sono disponibili in riferimento agli errori; ottenere una chiave richiede un minuto tramite registrazione e la guida all’autenticazione.