L’API a vérifié la signature d’un bloc de réflexion que vous lui avez renvoyé, mais la vérification a échoué : la signature a été tronquée, modifiée ou renvoyée vide, ou bien le bloc n’a jamais été signé par Claude — ou, avec Claude Fable 5.1 et Claude Opus 5.5, un élément antérieur de la conversation a changé. Renvoyer le même historique échoue de la même manière à chaque fois. Trouvez ce qui l’a invalidée, puis supprimez une fois les blocs de réflexion de cette conversation et continuez — vous perdez le raisonnement antérieur du modèle, pas la conversation.
L’erreur
// 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"."Causes et solutions en bref
| Cause | Solution |
|---|---|
| La signature a été tronquée, vidée ou modifiée avant son renvoi | Stockez et rejouez chaque bloc exactement tel qu’il a été renvoyé. Laissez le SDK assembler les tours diffusés afin de ne pas perdre le signature_delta. |
| Le bloc n’a jamais été signé par Claude | Un modèle autre que Claude derrière une URL compatible Anthropic, ou un proxy qui écrit ses propres signatures. Renvoyez ces tours uniquement sous forme de texte et de tool_use. |
| Vous avez changé d’URL de base, de compte ou de connexion au milieu de la conversation | Claude Code 2.1.152+ supprime les signatures obsolètes après un changement de modèle ou de connexion. Dans votre propre code, supprimez les blocs de réflexion une fois si la première requête suivant un changement échoue. |
| « Le bloc est associé à une autre conversation » (Fable 5.1, Opus 5.5) | Le prompt système, les outils ou un message antérieur a changé. Conservez un historique en ajout uniquement, ou activez drop_block (nécessite un en-tête bêta). |
| Un proxy ou une passerelle réécrit l’historique lors du passage | Ses réécritures sont considérées comme vos modifications. Reproduisez le problème directement auprès de l’API pour confirmer ou écarter cette cause. |
Lisez quelle vérification a échoué
La formulation vous l’indique. Un message qui s’arrête à « Invalid `signature` in `thinking` block » signifie que la signature elle-même n’a pas été vérifiée : Anthropic cite comme causes une signature tronquée, modifiée ou renvoyée vide (https://platform.claude.com/docs/en/build-with-claude/thinking-troubleshooting, en septembre 2026), et sa page sur la réflexion préservée parle d’une signature altérée ou indéchiffrable qui renvoie toujours une erreur 400. Un chemin masqué sous la forme ***.***.content.0 ou un identifiant de requête ajouté par une passerelle ne change rien ; ce qui compte est la présence ou non d’une phrase concernant la conversation. Avec Claude Fable 5.1 et Claude Opus 5.5, les mêmes mots peuvent être suivis de « The block is bound to a different conversation » — il s’agit d’une autre vérification, traitée à la dernière étape. Un troisième message, « blocks in the latest assistant message cannot be modified », signifie que le dernier tour de l’assistant a été modifié, filtré, réordonné ou reconstruit ; un texte de réflexion modifié produit cette erreur, et non une erreur de signature. Réessayer le même corps ne résout aucun de ces problèmes.
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 backRenvoyez les tours de l’assistant exactement tels qu’ils ont été renvoyés
Chaque bloc de réflexion contient une signature — une copie chiffrée de l’intégralité du raisonnement — et l’API l’utilise pour vérifier que le bloc a été généré par Claude (https://platform.claude.com/docs/en/build-with-claude/thinking#thinking-encryption). Ajoutez la liste content de la réponse sans la modifier : blocs thinking, redacted_thinking et tool_use, y compris les blocs thinking dont le texte est vide, ce qui constitue l’affichage par défaut des modèles plus récents. En mode streaming, la signature arrive dans un unique signature_delta juste avant la fermeture du bloc ; un accumulateur écrit manuellement qui le rate stocke une signature vide, et un bloc renvoyé avec une signature vide échoue. Anthropic recommande de laisser le SDK assembler le message. L’ordre des clés JSON et les espaces ne comptent pas — les valeurs, si.
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.Gardez la réflexion des autres backends hors de l’historique de Claude
Selon la documentation d’Anthropic, changer de modèle Claude sur sa propre API n’est pas censé déclencher ce problème : elle vous demande de continuer à envoyer les blocs lors du changement, supprime ceux que le nouveau modèle ne peut pas lire sans erreur et documente les signatures comme portables entre l’API Claude, Amazon Bedrock et Google Cloud (https://platform.claude.com/docs/en/build-with-claude/thinking, en septembre 2026). En revanche, elle ne peut pas vérifier un bloc que Claude n’a jamais signé. Les signalements publics concernent des historiques passés par un autre backend : une session Claude Code exécutée sur un backend GLM puis revenue à Anthropic (github.com/anthropics/claude-code/issues/21726), des tours Gemini qu’un proxy a présentés comme des blocs de réflexion Claude avec ses propres signatures (github.com/router-for-me/CLIProxyAPI/issues/1584), ou une session Claude Code passée à une autre clé puis revenue à la précédente (github.com/lbjlaq/Antigravity-Manager/issues/388). Pour les tours produits par un modèle autre que Claude, Anthropic recommande de renvoyer la sortie de ce modèle uniquement comme contenu textuel et tool_use.
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")]Récupérer une conversation qui échoue déjà
Supprimez une fois les blocs thinking et redacted_thinking de l’historique stocké — les supprimer tous est le plus simple ; pour la variante « bound to a different conversation », le minimum indiqué par Anthropic est le bloc nommé et tous ceux qui le suivent — puis conservez chaque autre bloc à sa place, enregistrez cet historique et continuez. Anthropic donne cette procédure comme récupération pour une session enregistrée qui ne peut plus être rejouée (https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#faq) ; lorsqu’une signature n’est pas vérifiée, la seule autre solution consiste à rejouer le bloc exactement tel qu’il a été renvoyé, si vous l’avez encore. Claude Code supprime lui-même les réflexions antérieures lorsque l’API rejette une signature. Une fois les blocs supprimés et la session poursuivie, ne les remettez pas : sur Fable 5.1, un bloc supprimé puis réinséré invalide la réflexion produite pendant son absence. Le modèle répond sans son raisonnement antérieur, et les nouvelles réflexions sont valides à partir de là. Dans Claude Code, 2.1.152 (27 mai 2026, https://code.claude.com/docs/en/changelog) supprime les signatures obsolètes après un changement de modèle ou de connexion, et son guide de passerelle indique qu’il réessaie un rejet de signature sans les blocs de réflexion antérieurs — mais cette nouvelle tentative s’appuie sur le texte d’erreur du fournisseur en amont, et une passerelle qui enveloppe les erreurs dans sa propre structure peut la perturber (https://code.claude.com/docs/en/llm-gateway-protocol#automatic-retry-and-error-forwarding).
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 blocksSur Fable 5.1, gardez le préfixe fixe — ou activez drop_block
« Bound to a different conversation » est la vérification de réflexion préservée : avec Claude Fable 5.1 et Claude Opus 5.5, un bloc rejoué n’est valide que si le prompt système, les outils et chaque message antérieur sont inchangés. Anthropic l’applique par défaut aux comptes créés le 31 août 2026 ou après (https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#enforcement) ; derrière une passerelle, ce compte ne vous appartient pas, supposez donc que la règle est active. Gardez le système et les outils fixes pendant la session et ajoutez les messages au lieu de les modifier. Pour que les requêtes continuent de réussir pendant que vous recherchez la modification, envoyez l’en-tête bêta thinking-binding-controls-2026-08-01 avec prefix_mismatch_behavior défini sur drop_block ; sans cet en-tête, le champ lui-même est rejeté avec « block_binding: Extra inputs are not permitted » (https://platform.claude.com/docs/en/api/errors).
# 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": "..."}]
}'Si vous appelez via Kunavo
Kunavo transmet les blocs thinking et redacted_thinking via /v1/messages tels qu’ils sont envoyés, signature et données incluses — les seuls changements apportés à la requête sont l’identifiant du modèle et, pour les modèles qui les rejettent, la suppression de temperature, top_p et top_k — puis renvoie le corps de la réponse, en streaming ou non, tel qu’il a été envoyé par le fournisseur en amont. En septembre 2026, chaque modèle Claude est servi par un seul canal en amont sans solution de repli ; le routage de Kunavo ne déplace donc pas une conversation entre fournisseurs, et une erreur 400 n’est jamais réessayée ailleurs. Nous n’avons pas testé le déplacement d’une conversation entre Anthropic direct et Kunavo ; prévoyez donc que la première requête après un tel changement devra supprimer la réflexion. Depuis le 24 septembre 2026, Kunavo transmet la version bêta thinking-binding-controls-2026-08-01 ; lors d’un test effectué ce jour-là, le canal servant Claude a accepté block_binding sur Claude Fable 5.1 avec ou sans l’en-tête, et nous ne l’avons pas vu supprimer de bloc. Le rejet arrive sous la forme d’une erreur HTTP 400 de type invalid_request_error, sans champ request_id, contenant le texte du message du fournisseur en amont — qui peut masquer le chemin messages.N et se terminer par l’identifiant de requête propre à ce fournisseur — faites donc la correspondance sur le statut et les mots « Invalid `signature` in `thinking` block ». La suppression et la nouvelle tentative automatiques de Claude Code s’appuient sur cette formulation : Claude Code 2.1.280, dirigé vers un serveur de test qui répondait avec cette structure, a supprimé les blocs de réflexion et réessayé. Nous n’avons pas déclenché l’erreur via Kunavo lui-même ; si une session échoue encore à chaque tour, commencez-en une nouvelle. Les requêtes échouées ne sont pas facturées. Ce que l’endpoint natif transmet sans modification est indiqué dans la référence de l’API Messages.
Questions fréquentes
Que signifie « Invalid `signature` in `thinking` block » ?
L’API n’a pas pu vérifier un bloc de réflexion que vous lui avez renvoyé. Chaque bloc de réflexion contient une signature — une copie chiffrée du raisonnement de Claude — et la vérification échoue lorsque cette signature a été tronquée, modifiée ou renvoyée vide, ou lorsque le bloc n’a jamais été signé par Claude. Il s’agit d’une erreur 400, et non d’une erreur transitoire : la même requête échoue à chaque fois.
Les signatures des blocs de réflexion expirent-elles ?
La documentation d’Anthropic ne mentionne aucune expiration. Sur le suivi anthropic-sdk-python (problème #1598, août 2026), une réponse provenant d’un compte que GitHub identifie comme contributeur indique que non, et que la vérification échoue lorsque le bloc qui atteint l’API diffère de celui qui a été renvoyé — il s’agit d’un commentaire sur un problème, pas de la documentation. Si une session enregistrée qui fonctionnait auparavant échoue maintenant, examinez ce qui a pu modifier les blocs stockés ou le chemin qu’ils ont emprunté : votre couche de stockage, un proxy ou un changement de backend.
Puis-je simplement supprimer les blocs de réflexion et continuer ?
Oui. Anthropic le donne comme procédure de récupération pour une session enregistrée qui ne peut pas être rejouée, et Claude Code supprime lui-même les réflexions antérieures lorsqu’une signature est rejetée. Supprimez les blocs thinking et redacted_thinking — les supprimer tous est le plus simple — conservez les autres blocs et réessayez une fois. Le modèle perd son raisonnement antérieur, pas la conversation ; en dehors de l’utilisation d’outils, la documentation d’Anthropic autorise de toute façon l’omission de la réflexion des tours précédents.
Pourquoi cela se produit-il après un changement de modèle ou de fournisseur ?
La documentation d’Anthropic indique qu’un changement entre modèles Claude sur son API supprime sans erreur les blocs que le nouveau modèle ne peut pas lire, et que les signatures fonctionnent entre l’API Claude, Amazon Bedrock et Google Cloud. Claude Code a néanmoins dû corriger des sessions bloquées par des signatures obsolètes après un changement de modèle ou de connexion (2.1.152), et les signalements publics concernent des historiques passés par quelque chose que Claude ne peut pas vérifier — un modèle autre que Claude derrière la même URL de base, un proxy qui écrit ses propres signatures ou un client qui les a perdues. Supprimez les blocs de réflexion une fois après le changement.
Claude Code corrige-t-il automatiquement ce problème ?
Les versions récentes essaient de le faire. Depuis 2.1.152, il supprime les signatures obsolètes après un changement de modèle ou de connexion, et réessaie un rejet de signature sans les blocs de réflexion antérieurs. Cette nouvelle tentative s’appuie sur le texte d’erreur du fournisseur en amont, et le guide des passerelles d’Anthropic indique qu’une passerelle qui enveloppe les erreurs dans sa propre structure peut la perturber. Exécutez d’abord claude update ; si une session échoue encore à chaque tour, commencez-en une nouvelle.
Guides associés
- API Claude 400 « tool_use ids were found without tool_result blocks » — la règle d’ordre
- Claude Code Router — acheminer Claude Code vers n’importe quel modèle, ou se passer entièrement du routeur
- Erreurs de streaming LLM — coupures SSE, flux bloqués et utilisation manquante
- Claude Code « context_management: Extra inputs are not permitted » — l’en-tête bêta qui n’est pas arrivé
La sémantique détaillée des erreurs est disponible dans référence des erreurs ; obtenir une clé prend une minute via inscription et la guide d’authentification.