messages 配列が assistant ターンで終わっている場合、Claude 4.6 以降のモデルはそれを prefill と解釈して拒否します。会話を user メッセージで終了し、prefill が担っていた処理 — JSON の強制、前置きの省略、ペルソナの維持、途中で切れた回答の再開 — を、Anthropic が文書化している代替手段に移してください。
エラー
{
"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_..."
}原因と対処法の概要
| 原因 | 対処法 |
|---|---|
| messages の最後のエントリの role が "assistant" になっている | これは prefill であり、Claude 4.6 以降のモデルでは拒否されます。user メッセージで終了してください。 |
| フレームワークによって空の assistant メッセージが最後に残されている | 送信前に、末尾にある内容なしの assistant メッセージを削除してください。 |
| JSON を強制するために「{」を prefill した | 代わりに構造化出力(output_config.format)を使用してください。 |
| 前置きを省略する、ペルソナを維持する、または途中で切れた回答を再開するために prefill した | system prompt の指示、system prompt 内の role、または user ターンによる継続を使用します。 |
| メモリーマネージャー、エージェントループ、ハンドオフによって assistant ターンが最後に残された | すべてのコードパスで処理するのではなく、リクエスト直前に末尾を一度正規化してください。 |
prefill を拒否する Claude モデル(2026年9月時点)
Anthropic のエラーリファレンスは明確です。Claude 4.6 以降のモデルは最後の assistant message の prefill をサポートしておらず、そのようなリクエストはまさにこの 400 エラーになります(https://platform.claude.com/docs/en/api/errors#prefill-not-supported)。モデル名で言えば、Claude Opus 4.6 と、それ以降のすべての Opus(Claude Opus 5.5 を含む)(https://platform.claude.com/docs/en/models/opus-5-5/migration-guide)、Claude Sonnet 4.6 と Claude Sonnet 5(https://platform.claude.com/docs/en/models/sonnet-5/migration-guide)、Claude Fable 5 と Fable 5.1(https://platform.claude.com/docs/en/models/fable-5-1/migration-guide)が該当します。Claude Haiku 4.5 は引き続き prefill を受け付け、Claude Sonnet 4.5 と Claude Opus 4.5 も同様です。そのため、このエラーはコード変更よりもモデル ID の変更に伴って発生しやすくなります。会話の途中にある assistant message(few-shot 例を含む)は影響を受けません。
user ターンで終了する — 1行の修正を含む
意図的に prefill を書いた人がいないこともよくあります。スタック内の何かが assistant message を最後に追加しているのです。公開された報告では、1つを追加するメモリーマネージャー(Strands issue #1694)、未完了だと誤認したターンの後に再リクエストするエージェントループ(opencode issue #46415)、連続した返信とエージェントのハンドオフ(LiveKit issue #4907)、末尾に残された空の assistant message(AutoGen PR #7931)が原因として挙げられています。末尾のメッセージが空なら削除してください。それが1行で済む修正です。継続したいテキストが含まれている場合は、Anthropic の移行ガイダンスに従い、回答がどこで止まったかを引用した継続内容を user message に入れてください。変更せず残すべき文書化された例外が1つあります。web search などのサーバーツールからの pause_turn は、停止した assistant の内容をそのまま再送して継続します(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)プレフィルが行っていた処理を置き換える
Anthropicのプロンプトガイドでは、プレフィルの従来の各用途に対する置き換え方法が説明されています(https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#migrating-away-from-prefilled-responses)。JSONを強制する場合:レスポンスをスキーマに制約する構造化出力。Claude Haiku 4.5、Sonnet 4.5、Opus 4.5、およびそれ以降のすべてのモデルで利用できます(https://platform.claude.com/docs/en/build-with-claude/structured-outputs)。YAMLやその他の形式の場合、ガイドでは構造を要求し、合わなければ再試行するよう勧めています。分類:有効なラベルを列挙したツール、または構造化出力。前置きの省略:システムプロンプトに「前置きなしで直接回答してください」などと指示する。ペルソナの維持:システムプロンプトで役割を設定し(https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#give-claude-a-role)、プレフィルしたassistantメッセージの代わりに、ユーザーメッセージ内に定期的なリマインダーを入れます。途中で途切れた回答:上記のユーザーメッセージによる継続。ツール呼び出しの強制は、どこでもそのまま置き換えられるわけではありません。Claude Fable 5.1とClaude Opus 5.5では、tool_choice anyおよびtoolがサポートされず、それぞれ独自の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
}
}
}
}'Kunavo経由で呼び出している場合
Kunavoは末尾のassistantターンを転送しますが、修復は行いません。/v1/messagesではmessages配列をそのまま上流へ渡し、/v1/chat/completionsでは、変換処理が最後のrole: "assistant"メッセージをClaudeリクエストの最後のassistantターンとして引き継ぎます。空のメッセージも含まれるため、空のものは自分で削除してください。Anthropicは、claude-haiku-4-5を除く、当社が提供するすべてのclaude-*モデルで、プレフィルされた最後のターンを拒否します。この400エラーは、メッセージ本文をそのまま含み、続けて上流のrequest idが返されます。/v1/messagesではAnthropic形式で、エラーの型はAnthropic APIと同じinvalid_request_error(2026年9月24日より前はapi_error)、/v1/chat/completionsではOpenAI形式(type upstream_error、code upstream_400)です。400エラーが別のチャネルで再試行されることはなく、失敗した呼び出しは費用0で記録されます。JSONの場合は、プレフィルではなくスキーマを送信してください。/v1/messagesでは送信したoutput_configをそのまま転送し、/v1/chat/completionsではtype json_schemaのresponse_formatをoutput_config.formatに変換します。2026-09-24時点では、このフィールドにより、当社が提供するすべてのclaude-*モデルで返信がスキーマに制約されます。json_object response_formatに対応するClaude側の機能はなく、強制もされません。また、スキーマをプレフィルされた最後のターンと同時に送ると、claude-haiku-4-5を含め、独自の400エラーになります:「When using output format, pre-filling the `assistant` response is not supported.」 ネイティブエンドポイントと、それが通過させるリクエスト形式については、 Messages APIのドキュメント.
よくある質問
assistantメッセージのプレフィルをサポートしていないClaudeモデルはどれですか?
2026年9月時点のAnthropicのドキュメントによると、Claude 4.6以降のすべてのClaudeモデルです。Claude Opus 4.6とそれ以降のすべてのOpus、Claude Sonnet 4.6とSonnet 5、Claude Fable 5と5.1、そしてMythosモデルが該当します。Claude Haiku 4.5、Sonnet 4.5、Opus 4.5では、引き続き1つのプレフィルを受け付けます。
プレフィルなしでClaudeにJSON出力を強制するにはどうすればよいですか?
構造化出力を使用します。output_config.formatにJSONスキーマを渡すと、レスポンスがそのスキーマに制約されます。OpenAI互換エンドポイント経由では、type json_schemaのresponse_formatとして送信してください。Kunavoはこれをoutput_config.formatに変換します。Anthropicは、メッセージのプレフィルはどのような場合でもJSON出力と互換性がないと説明しています。
何もプレフィルしていないのに、なぜこのエラーが表示されるのですか?
スタック内の何かがassistantメッセージを最後に残しています。メモリまたはセッションマネージャー、ターン後に再リクエストするエージェントループ、エージェントの引き継ぎ、または誰も削除しなかった空のassistantメッセージなどが考えられます。messages配列を送信時のまま正確に記録してください。最後の要素にはrole: "assistant"が含まれます。
会話にassistantメッセージを引き続き含めることはできますか?
はい。制限されるのは最後のターンだけです。few-shot例を含む、それ以前のassistantメッセージには影響ありません。
OpenAI互換エンドポイント経由でも発生するのはなぜですか?
ゲートウェイが最後のrole: "assistant"メッセージを、最後のClaude assistantターンとして引き継ぐためです。形を変えた同じプレフィルです。Kunavoのchat translatorもまさにその処理を行い、同じメッセージは他のOpenAI互換ゲートウェイ経由でも報告されています(opencode issue #13768)。解決策は同じで、userメッセージで終わらせてください。
関連ガイド
- Claude API 400「tool_use ids were found without tool_result blocks」— 順序のルール
- 「`temperature` and `top_p` cannot both be specified for this model」 — どちらか一方を送信し、新しいClaudeモデルではどちらも送信しない
- 「Unsupported parameter: 'max_tokens' is not supported with this model」— max_completion_tokens を使用する
- Claude API — KunavoでClaudeを呼び出す完全ガイド