Votre tableau messages se termine par un tour assistant, et les modèles Claude 4.6 et ultérieurs l’interprètent comme un préremplissage et le refusent. Terminez la conversation par un message utilisateur, puis déplacez ce que faisait le préremplissage — imposer le JSON, éviter un préambule, maintenir un persona ou reprendre une réponse interrompue — vers le remplacement documenté par Anthropic.
L’erreur
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "This model does not support assistant message prefill. The conversation must end with a user message."
},
"request_id": "req_..."
}Causes et solutions en bref
| Cause | Solution |
|---|---|
| La dernière entrée de messages a le rôle : "assistant" | Il s’agit d’un préremplissage, et les modèles Claude 4.6 et ultérieurs le rejettent. Terminez par un message utilisateur. |
| Un framework a laissé un message assistant vide en dernier | Supprimez le message assistant final sans contenu avant l’envoi. |
| Vous avez prérempli « { » pour imposer le JSON | Utilisez plutôt les sorties structurées (output_config.format). |
| Vous avez utilisé un préremplissage pour éviter un préambule, conserver un persona ou reprendre une réponse interrompue | Une instruction dans le prompt système, un rôle dans le prompt système ou une continuation dans un tour utilisateur. |
| Un gestionnaire de mémoire, une boucle d’agent ou un transfert a laissé un tour assistant en dernier | Normalisez la fin une seule fois, juste avant la requête, plutôt que dans chaque chemin d’exécution. |
Quels modèles Claude rejettent le préremplissage (en septembre 2026)
La référence d’erreurs d’Anthropic est explicite : les modèles Claude 4.6 et ultérieurs ne prennent pas en charge le préremplissage du dernier message assistant, et une requête qui le fait renvoie exactement cette erreur 400 (https://platform.claude.com/docs/en/api/errors#prefill-not-supported). Par nom, cela concerne Claude Opus 4.6 et tous les Opus ultérieurs, y compris Claude Opus 5.5 (https://platform.claude.com/docs/en/models/opus-5-5/migration-guide) ; Claude Sonnet 4.6 et Claude Sonnet 5 (https://platform.claude.com/docs/en/models/sonnet-5/migration-guide) ; ainsi que Claude Fable 5 et Fable 5.1 (https://platform.claude.com/docs/en/models/fable-5-1/migration-guide). Claude Haiku 4.5 accepte encore le préremplissage, tout comme Claude Sonnet 4.5 et Claude Opus 4.5 — c’est pourquoi cette erreur survient souvent après un changement d’identifiant de modèle plutôt qu’après une modification du code. Les messages assistant antérieurs dans la conversation, y compris les exemples few-shot, ne sont pas concernés.
Terminez par un tour utilisateur — y compris pour la correction en une ligne
Souvent, personne n’a intentionnellement écrit de préremplissage : un élément de la pile a placé un message assistant en dernier. Des signalements publics l’attribuent à un gestionnaire de mémoire qui en ajoute un (problème Strands #1694), à une boucle d’agent qui relance une requête après un tour qu’elle croit à tort inachevé (problème opencode #46415), à des réponses consécutives et des transferts d’agents (problème LiveKit #4907), ainsi qu’à un message assistant vide laissé à la fin (PR AutoGen #7931). Si le message final est vide, supprimez-le — c’est la correction en une ligne. S’il contient du texte que vous voulez poursuivre, appliquez les indications du guide de migration d’Anthropic pour les continuations : placez la continuation dans un message utilisateur qui cite l’endroit où la réponse s’est arrêtée. Une exception documentée à laisser telle quelle : un pause_turn provenant d’outils serveur comme la recherche web se poursuit en renvoyant le contenu assistant mis en pause tel quel (https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools).
from openai import OpenAI
client = OpenAI(base_url="https://api.kunavo.com/v1", api_key="sk-kn-...")
def end_on_user(messages: list[dict]) -> list[dict]:
"""Claude 4.6 and later reject a conversation whose last turn is the assistant's."""
last = messages[-1] if messages else None
if not last or last["role"] != "assistant" or last.get("tool_calls"):
return messages # tool_calls are owed tool results instead
content = last.get("content")
if not content or (isinstance(content, str) and not content.strip()):
return messages[:-1] # the one line: drop an empty tail
tail = content[-200:] if isinstance(content, str) else "..."
return messages + [{
"role": "user",
"content": f"Your previous response was interrupted and ended with {tail!r}. "
"Continue from where you left off.",
}]
messages = [
{"role": "user", "content": "Explain HTTP caching in three bullets."},
{"role": "assistant", "content": ""}, # the empty tail a framework left behind
]
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=end_on_user(messages),
)
print(resp.choices[0].message.content)Remplacez ce que faisait le préremplissage
Le guide de prompting d’Anthropic associe chaque ancien usage du préremplissage à un remplacement (https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#migrating-away-from-prefilled-responses). Pour imposer le JSON : utilisez les sorties structurées, qui contraignent la réponse à votre schéma et sont disponibles sur Claude Haiku 4.5, Sonnet 4.5, Opus 4.5 et tous les modèles ultérieurs (https://platform.claude.com/docs/en/build-with-claude/structured-outputs) ; pour YAML ou un autre format, le guide conseille de demander la structure et de réessayer en cas d’écart. Pour la classification : utilisez un outil dont l’enum contient vos libellés valides, ou les sorties structurées. Pour éviter un préambule : une instruction dans le prompt système telle que « Répondez directement sans préambule. » Pour maintenir un persona : définissez le rôle dans le prompt système (https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#give-claude-a-role), et placez des rappels périodiques dans le tour utilisateur plutôt que dans un message assistant prérempli. Pour une réponse interrompue : utilisez la continuation dans le tour utilisateur ci-dessus. Forcer un appel d’outil n’est pas un substitut direct partout — Claude Fable 5.1 et Claude Opus 5.5 rejettent tool_choice any et tool avec leur propre erreur 400 (https://platform.claude.com/docs/en/api/errors#forced-tool-use-not-supported).
# Before: messages ended with {"role": "assistant", "content": "{"}
# Kunavo forwards output_config as sent; the reply is constrained to the schema.
curl https://api.kunavo.com/v1/messages \
-H "x-api-key: sk-kn-..." \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Extract the name and email: John Smith <john@example.com>"}
],
"output_config": {
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"}
},
"required": ["name", "email"],
"additionalProperties": false
}
}
}
}'Si vous appelez via Kunavo
Kunavo transmet un tour assistant final ; il ne le corrige pas. /v1/messages transmet votre tableau messages en amont sans modification, et sur /v1/chat/completions le traducteur transmet un message final role: "assistant" comme tour assistant final dans la requête Claude — y compris s’il est vide ; supprimez donc vous-même les messages vides. Anthropic rejette un tour final prérempli sur tous les modèles claude-* que nous proposons, à l’exception de claude-haiku-4-5, et cette erreur 400 vous parvient avec le texte du message intact, suivie de l’identifiant de requête amont : au format Anthropic sur /v1/messages, avec le type invalid_request_error comme dans l’API Anthropic (jusqu’au 24 septembre 2026, il s’agissait de api_error), et au format OpenAI sur /v1/chat/completions (type upstream_error, code upstream_400). Une erreur 400 n’est jamais réessayée sur un autre canal, et l’appel échoué est enregistré avec un coût nul. Pour le JSON, envoyez un schéma plutôt qu’un préremplissage : /v1/messages transmet output_config tel que vous l’avez envoyé, et sur /v1/chat/completions un response_format de type json_schema est converti en output_config.format. Au 2026-09-24, ce champ contraignait la réponse au schéma sur tous les modèles claude-* que nous proposons. Un response_format json_object n’a pas d’équivalent Claude et n’est pas appliqué, et un schéma envoyé avec un tour final prérempli génère sa propre erreur 400, y compris avec claude-haiku-4-5 : "When using output format, pre-filling the `assistant` response is not supported." Le point de terminaison natif, ainsi que la structure de requête qu’il transmet, sont documentés dans la documentation de l’API Messages.
Questions fréquentes
Quels modèles Claude ne prennent pas en charge le préremplissage d’un message assistant ?
Selon la documentation d’Anthropic en septembre 2026, tous les modèles Claude à partir de la version 4.6 : Claude Opus 4.6 et tous les Opus ultérieurs, Claude Sonnet 4.6 et Sonnet 5, Claude Fable 5 et 5.1, ainsi que les modèles Mythos. Claude Haiku 4.5, Sonnet 4.5 et Opus 4.5 en acceptent encore un.
Comment forcer une sortie JSON de Claude sans préremplissage ?
Utilisez les sorties structurées : transmettez un schéma JSON dans output_config.format et la réponse sera contrainte par celui-ci. Via un point de terminaison compatible OpenAI, envoyez-le comme response_format avec type json_schema ; Kunavo le convertit en output_config.format. Anthropic indique que le préremplissage des messages est incompatible avec les sorties JSON dans tous les cas.
Pourquoi cette erreur apparaît-elle alors que je n’ai rien prérempli ?
Un élément de votre pile a laissé un message assistant en dernier — un gestionnaire de mémoire ou de session, une boucle d’agent relançant une requête après un tour, un transfert d’agent ou un message assistant vide que personne n’a supprimé. Consignez exactement le tableau messages tel qu’il est envoyé ; son dernier élément aura le rôle : "assistant".
Puis-je encore inclure des messages assistant dans la conversation ?
Oui. Seul le tour final est restreint ; les messages assistant antérieurs, y compris les exemples few-shot, ne sont pas concernés.
Pourquoi cela se produit-il aussi via un point de terminaison compatible OpenAI ?
Parce que la passerelle transmet votre message final role: "assistant" comme tour assistant final de Claude — le même préremplissage, sous une autre forme. Le traducteur de chat de Kunavo fait exactement cela, et le même message a été signalé via d’autres passerelles compatibles OpenAI (problème opencode #13768). La correction est la même : terminez par un message utilisateur.
Guides associés
- API Claude 400 « tool_use ids were found without tool_result blocks » — la règle d’ordre
- « `temperature` et `top_p` ne peuvent pas être spécifiés simultanément pour ce modèle » — envoyez-en un seul, et aucun avec les modèles Claude plus récents
- « Unsupported parameter: 'max_tokens' is not supported with this model » — utilisez max_completion_tokens
- API Claude — le guide complet pour appeler Claude sur Kunavo
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.