Claude Platform Docs
MessagesRéflexion préservée

Corriger un bloc de réflexion lié à une conversation différente

Relancez une conversation après l’erreur 400 indiquant qu’un bloc de réflexion est lié à une conversation différente, trouvez ce que votre code a modifié, et vérifiez par un test que la modification a disparu.

Renvoyer la même requête ne peut pas fonctionner, car votre historique contient toujours ce que votre code a modifié. Envoyez "drop_block" pour arrêter les erreurs maintenant. Le correctif à long terme consiste à rendre votre code « append-only » (en ajout seul).

Erreur : The block is bound to a different conversation

Le « thinking block » (bloc de réflexion) a échoué à la vérification du préfixe : quelque chose placé avant lui a changé après que Claude l’a produit (voir Ce qui compte comme une modification), ou un bloc de réflexion situé entre d’autres a été omis ou déplacé. L’erreur ressemble à ceci, et peut ensuite nommer ce qui a changé :

messages.1.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".

« A different conversation » signifie un contenu différent avant le bloc : la vérification du préfixe ne compare ni les sessions ni les utilisateurs. Le message d’erreur indique de supprimer le bloc, mais supprimer uniquement ce bloc ne suffit pas. D’autres erreurs peuvent sembler similaires.

Si l’application n’est pas la vôtre, démarrez une nouvelle conversation et prévenez son mainteneur. Si vous avez supprimé un secret, des données personnelles ou du texte injecté, ou si vos requêtes désactivent la réflexion, supprimez la réflexion manuellement au lieu de l’étape 1.

  1. Arrêter les erreurs maintenant

    Définissez thinking.block_binding.prefix_mismatch_behavior sur "drop_block", et envoyez l’en-tête bêta anthropic-beta: thinking-binding-controls-2026-08-01. Faites-le à chaque requête ultérieure de la conversation, car l’API ne stocke pas le réglage entre les requêtes. Une conversation enregistrée contient toujours la modification, même après que vous avez corrigé votre code ; stockez donc le réglage avec elle. Définissez type sur "adaptive", comme indiqué :

    {
      "thinking": {
        "type": "adaptive",
        "block_binding": {
          "prefix_mismatch_behavior": "drop_block"
        }
      }
    }

    Dans le SDK, appelez la méthode Messages bêta et transmettez la valeur de l’en-tête, comme le fait le programme de test. Si l’erreur demande toujours l’en-tête, l’en-tête n’est pas arrivé.

    Cela arrête les erreurs en écartant la réflexion invalide, mais cela peut coûter plus cher et peut affecter la qualité des sorties et la latence. La requête suivante réussit, et son tableau input_transformations liste chaque bloc que l’API a écarté.

    Si vos requêtes ne définissent pas le paramètre thinking, l’ajouter ne change rien d’autre, car les modèles avec réflexion préservée réfléchissent de manière adaptative par défaut.

  2. Correctif à long terme

    Rendez votre intégration en ajout seul :

    1. Trouvez la modification. L’erreur peut la nommer. Pour trouver où votre code l’effectue, exécutez claude update, puis exécutez /claude-api preserved-thinking-migration dans Claude Code, dans le dépôt de votre code. Ou cherchez manuellement.
    2. Cessez d’effectuer la modification, sinon les nouvelles conversations peuvent aussi recevoir l’erreur. Envoyez plutôt une mise à jour à la fin.
    3. Continuez d’envoyer à chaque conversation en cours le system et les tools de sa dernière requête réussie.

Si la modification est récente, vous pouvez plutôt l’annuler : rétablissez ce que votre code a modifié. La réflexion d’avant la modification redevient valide. La réflexion produite depuis échoue, donc supprimez-la ou continuez d’envoyer "drop_block".

Ce que coûte le fait d’écarter la réflexion

Claude peut dépenser davantage de tokens de sortie pour reconstruire un raisonnement qu’il ne peut plus lire. Écarter les blocs invalide aussi le cache des prompts à partir du premier bloc écarté.

Lorsque quelque chose change à chaque tour, chaque tour perd la réflexion des tours précédents, donc l’augmentation se répète. Exécutez des évaluations sur votre propre charge de travail avant de vous appuyer sur "drop_block".

Requête 1
erreur 400
avec drop_block
Requête 2
Requête 3
Requête 4
réflexion, écartée
réflexion, conservée
nouvelle
une modification par votre code

Utilisez "drop_block" pour faire avancer les conversations existantes tant qu’elles contiennent une modification que vous êtes en train de corriger, ainsi que lorsque vous écartez des blocs de manière planifiée, par exemple après votre propre résumé. Ne le laissez pas activé pour masquer une modification que votre code continue d’effectuer. Vous pouvez cesser de l’envoyer une fois les blocs invalides retirés de l’historique.

Trouver ce que votre code a modifié

La modification se trouve avant le premier bloc que l’API nomme. L’erreur 400 peut indiquer ce qui a changé, comme system, tools, un bloc de réflexion manquant ou le premier message qui diffère. Sans erreur, ou avec une erreur qui ne le précise pas, partez de ce dont vous disposez, comme une entrée prefix_binding_mismatch ou davantage de tokens de sortie.

Tester votre code pour détecter les échecs de la vérification du préfixe

Vous pouvez vous fier à un test une fois que vous l’avez vu échouer. D’abord, via votre propre code, exécutez une session qui fait réfléchir Claude, et modifiez quelque chose volontairement. Envoyez "drop_block" pour cette étape, afin que la réponse liste chaque bloc invalide au lieu de s’arrêter au premier, comme le montrent cinq étapes et un programme.

Ensuite, retirez cette modification et exécutez vos vraies sessions. À chaque requête, envoyez l’en-tête bêta thinking-binding-controls-2026-08-01, et définissez prefix_mismatch_behavior sur "error", afin qu’une modification effectuée par votre code dans ces sessions fasse échouer le build avec l’erreur 400.

Testez des sessions qui compactent, ajoutent des outils tardivement, modifient les instructions, changent de modèle ou reprennent : les tours simples n’atteignent pas ce code.

Une exécution propre n’a aucune entrée prefix_binding_mismatch et aucune erreur. Elle montre seulement que les blocs qu’elle a vérifiés sont valides, dans les sessions que vous avez exécutées. Elle ne prouve rien si :

Surveiller la production et repérer le raisonnement perdu sans erreur

Journalisez chaque erreur 400, et gérez-la dans le code pour que la conversation continue. Si, à la place, vos requêtes n’incluent pas prefix_mismatch_behavior, surveillez le trafic de production pour repérer la réflexion qui échoue à la vérification du préfixe et qui a atteint Claude.

Le raisonnement peut être perdu sans erreur via "drop_block", un élément de lot, un changement de modèle, un passage à un autre compte, ou du code qui ne renvoie aucune réflexion. Avec l’en-tête bêta, chacun laisse une entrée, sauf le dernier. Pour celui-ci, vérifiez que vos requêtes contiennent des blocs thinking.

Détails techniques

Ce que le message d’erreur peut indiquer d’autre

Le message d’erreur poursuit en nommant ce qui a changé, lorsque l’API peut le déterminer, comme system, tools, le premier message ou bloc qui diffère, du contenu manquant ou nouveau, ou un bloc de réflexion antérieur manquant ou dans le désordre. La formulation de cette phrase peut changer, ne faites donc pas de correspondance sur celle-ci. Si la requête n’avait pas d’en-tête bêta, le message d’erreur ajoute cette phrase :

That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.

L’erreur demande toujours l’en-tête, ou indique Extra inputs are not permitted

Si l’erreur demande toujours l’en-tête, celui-ci n’a pas atteint l’API : un proxy ou une bibliothèque l’a peut-être supprimé. Une autre erreur, se terminant par block_binding: Extra inputs are not permitted, signifie la même chose, ou que la réflexion est désactivée.

Supprimer manuellement la réflexion invalide

Utilisez cette méthode lorsque vous ne pouvez pas envoyer le réglage, ou dans l’un de ces cas :

  • Après avoir supprimé un secret, des données personnelles ou du texte injecté, car "drop_block" laisse la réflexion dans votre historique stocké.
  • Lorsque la réflexion est désactivée ("disabled" ou "between_tools"), car "drop_block" nécessite "adaptive", ce qui activerait la réflexion et ajouterait des tokens de sortie.
  1. Supprimez le bloc que l’erreur nomme, ainsi que chaque bloc thinking et redacted_thinking qui le suit, sinon la même erreur nommera ensuite le bloc invalide suivant. Mais si votre historique contient des messages role: "system", ou deux messages du même rôle d’affilée, supprimez tous les blocs thinking et redacted_thinking. L’erreur compte un tel message comme faisant partie du message qui le précède, donc la position qu’elle nomme peut être inférieure à l’index dans votre tableau. Le path d’une entrée input_transformations compte chaque message séparément.
  2. Conservez tous les autres blocs, et renvoyez la requête. Ne remettez pas les blocs supprimés.

Erreurs qui ressemblent à celle-ci

Ces erreurs n’indiquent pas que le bloc est lié à une conversation différente, et définir prefix_mismatch_behavior pourrait ne pas les résoudre :

Quand vous pouvez cesser d’envoyer "drop_block"

Pour cesser d’envoyer "drop_block", supprimez les blocs qu’il écarte et conservez la réflexion produite depuis. Si rien d’autre n’a changé, la conversation passe alors avec "error".

Gérer l’erreur dans le code

Pour gérer l’erreur dans le code, envoyez l’en-tête bêta et "error" à chaque requête, afin qu’un échec soit une erreur 400 sur tous les modèles. Lorsqu’elle survient, basculez uniquement cette conversation sur "drop_block" pour toutes les requêtes ultérieures, stockez ce choix avec elle, renvoyez une fois, et journalisez l’erreur. Si la même erreur revient, le réglage n’a pas atteint l’API : consultez L’erreur demande toujours l’en-tête, ou indique Extra inputs are not permitted.

Votre code doit reconnaître cette erreur par son champ message, ce qui constitue l’exception au conseil général de ne pas faire de correspondance sur le texte d’une erreur. Toutes les erreurs 400 ont le type invalid_request_error, et celle-ci n’a pas de error.details.error_code. Faites la correspondance uniquement sur « The block is bound to a different conversation », car le reste du message peut changer.

Vous n’avez pas d’erreur, ou une erreur qui n’indique pas ce qui a changé

  • L’erreur 400, sans modification nommée : Comparez les requêtes vous-même. Une cause possible est un bloc de compaction envoyé sans supprimer les messages qu’il résume.

  • Une entrée prefix_binding_mismatch : Comparez system, tools et messages jusqu’au path de la première entrée avec la conversation telle qu’elle était lorsque ce bloc a été produit. Si tous les blocs sont listés, commencez par system et tools.

    Si rien ne diffère, cherchez une URL d’image ou de document dont le contenu a changé, la liste d’outils modifiée d’un serveur MCP (voir Épingler la liste d’outils d’un serveur MCP), ou un bloc de réflexion omis, déplacé ou remis. Sans journaux de requêtes, renvoyez la requête avec "error", et lisez la phrase qui indique ce qui diffère, s’il y en a une.

  • Un proxy ou une bibliothèque qui n’est pas le vôtre, entre les deux : Comparez ce qu’il envoie avec ce que vous avez envoyé, et orientez son mainteneur vers Bibliothèques, proxys et passerelles.

  • Seulement un soupçon, et pas de Claude Code : Capturez les corps de requête d’une conversation, une qui comporte une compaction ou une modification d’outils. Comparez chacun avec le précédent, en laissant de côté ses nouveaux tours.

Cinq étapes pour un test qui peut échouer, et un programme qui les exécute

  1. Dans votre propre code, envoyez l’en-tête bêta et "drop_block" à chaque requête d’une session, vers un modèle avec réflexion préservée.
  2. Utilisez des prompts qui font réfléchir Claude, et vérifiez que la première réponse contient un bloc thinking. Avec la réflexion adaptative, Claude peut ne pas réfléchir sur un prompt facile.
  3. Faites échouer le test uniquement sur une entrée input_transformations dont la raison est prefix_binding_mismatch. Un test qui attend un tableau vide échoue aussi après un changement de modèle, car des entrées avec model_binding_mismatch ou organization_binding_mismatch sont alors attendues.
  4. Modifiez quelque chose volontairement, par exemple en ajoutant un prompt system uniquement à la troisième requête.
  5. Vérifiez que input_transformations liste les blocs de réflexion situés après la modification. S’il n’en liste aucun, vérifiez que l’historique contient un bloc de réflexion.

Ce programme effectue les étapes 1, 2, 4 et 5. Il affiche combien de blocs de réflexion et d’entrées input_transformations contient chaque réponse, puis chaque entrée, ce que vérifie l’étape 3 :

client = anthropic.Anthropic()

user_turns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many have exactly 8?",
    "How many have exactly 10?",
]

messages = []
for turn, user_turn in enumerate(user_turns, start=1):
    messages.append({"role": "user", "content": user_turn})
    response = client.beta.messages.create(
        model="claude-opus-5-5",
        max_tokens=16000,
        thinking={
            "type": "adaptive",
            "block_binding": {"prefix_mismatch_behavior": "drop_block"},
        },
        # Seule la dernière requête ajoute une invite système, ce qui modifie volontairement le préfixe.
        system="Answer briefly." if turn == len(user_turns) else anthropic.omit,
        messages=messages,
        betas=["thinking-binding-controls-2026-08-01"],
    )
    messages.append({"role": "assistant", "content": response.content})
    thinking_blocks = sum(block.type == "thinking" for block in response.content)
    entries = response.input_transformations or []
    print(f"thinking blocks: {thinking_blocks}, entries: {len(entries)}")
    for entry in entries:
        if entry.type == "thinking_dropped":
            print(entry.type, entry.path, entry.reason)
Output
thinking blocks: 1, entries: 0
thinking blocks: 1, entries: 0
thinking blocks: 1, entries: 2
thinking_dropped messages.1.content.0 prefix_binding_mismatch
thinking_dropped messages.3.content.0 prefix_binding_mismatch

Avec "error" à la place de "drop_block", la troisième requête reçoit l’erreur 400.

Ce que signifie chaque entrée input_transformations, et lesquelles sont à vous de corriger

Avec l’en-tête bêta, une réponse d’un modèle qui prend en charge la réflexion comporte le tableau input_transformations à côté de usage. Il est vide lorsque rien n’a été écarté et que rien d’invalide n’a été laissé passer. En streaming, il se trouve dans le message de l’événement message_start ; après un repli en cours de stream, l’événement message_delta final porte celui qui compte. Contrairement à la position indiquée par l’erreur, path est toujours l’emplacement du bloc tel que vous l’avez envoyé :

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

Le type et la reason de chaque entrée, et ce qu’ils signifient :

  • thinking_dropped, prefix_binding_mismatch : Ce qui précède ce bloc n’est pas ce qu’il a enregistré. À vous de corriger : Trouver ce que votre code a modifié.
  • thinking_mismatch_allowed, prefix_binding_mismatch : La même chose, mais Claude a lu le bloc sans modification, et il est facturé. Cette entrée n’apparaît que lorsque la requête n’inclut pas le réglage, sur certains modèles. À vous de corriger.
  • thinking_dropped, model_binding_mismatch : Ce modèle ne peut pas lire les blocs du modèle qui a produit celui-ci. Pas à vous de corriger : continuez d’envoyer toute la conversation.
  • thinking_dropped, organization_binding_mismatch : Un autre compte a produit le bloc, donc l’API l’a écarté. Pas à vous de corriger.

Ignorez une entrée dont vous ne reconnaissez pas le type ou la reason.

Lots et comptage des tokens

  • Lots de messages : Un élément qui n’inclut pas prefix_mismatch_behavior ne reçoit jamais l’erreur 400. L’API écarte les blocs invalides ou, sur certains modèles, peut les laisser passer. Un élément qui définit "error" se résout en errored lorsqu’un bloc échoue à la vérification du préfixe. block_binding se place dans le params.thinking de l’élément.
  • Comptage des tokens : Sur la Claude API, le comptage des tokens peut renvoyer la même erreur 400, et accepte prefix_mismatch_behavior sous le même en-tête. Il exclut du décompte les blocs écartés, et ne renvoie aucun input_transformations.

Étapes suivantes

Ce qu’il faut envoyer à la place de chaque modification que votre code apporte à une conversation.

Ce qu’est la réflexion préservée, ce à quoi un bloc de réflexion est lié, et le changement de modèle ou de compte.

Correctifs pour d’autres erreurs de réflexion, comme une signature qui ne se vérifie pas.

Cette page vous a-t-elle été utile ?