Tips

Prefill is no longer supported: migrating prompts for newer Claude models

TL;DR

Newer Claude models reject last-turn assistant prefill with a 400 error. Move JSON and classification to structured outputs or enum tools, use system instructions and XML tags to skip preambles, and audit old code before switching models.

If you've written prompts for older Claude models, you've probably used the prefill trick: pre-filling the start of the assistant's reply, such as { to force JSON, or "Here is the summary:" to skip a preamble. According to Anthropic's docs, starting with Claude 4.6 models, prefill on the last assistant turn is no longer supported: such requests return a 400 error. If you're upgrading models, here's what to fix.

What exactly changed

  • A request ending in a partially filled assistant message (prefill) sent to newer models → 400 error.
  • Earlier models still support prefill.
  • Assistant messages elsewhere in the conversation (chat history) are unaffected.
  • Anthropic's reasoning: instruction following is now good enough that most use cases no longer need prefill.

Migration table by purpose

You used prefill toDo this instead
Force JSON/YAMLUse structured outputs (schema-constrained), or ask clearly for the format with retries on parse failure
Classify into fixed labelsA tool with an enum field of valid labels, or structured outputs
Skip preambles ("Here is…")A system prompt instruction to answer directly without preamble; or output in XML tags and extract; strip any leftovers in post-processing
Steer around needless refusalsClear prompting in the user message; newer models refuse more appropriately
Continue an interrupted answerPut the existing text in the user message: "Your previous response was interrupted at […]. Continue from there"; or resend the request
Re-inject role or context periodicallyPut reminders in the user turn; in agent systems, inject via tools or during compaction

Example: skipping the preamble

# Before (prefill, 400 on newer models)
messages=[
  {"role": "user", "content": "Summarise the following text…"},
  {"role": "assistant", "content": "Summary:"},
]

# After
system="Respond directly. Don't start with phrases like 'Here is…' or 'Based on…'."
messages=[{"role": "user", "content": "Summarise the following text inside <summary>…"}]

Upgrade risks

  • Hidden breakage in old code: prefill often lives deep in shared helpers; find every request that ends with an assistant role.
  • Post-processing that depends on prefill: code doing "{" + response to rebuild JSON breaks once prefill goes; fix both together.
  • Formatting behaviour changes: rerun your evals after migrating, especially extraction and classification tasks.
  • Third-party libraries: older frameworks may add prefill automatically; check versions.

How to apply it

  • Dev: Grep the codebase for final messages with the assistant role; move every JSON use case to structured outputs.
  • Tech Lead: Add integration tests that send real requests to the new model before switching the production default.
  • PM: Put "remove prefill" on the model upgrade checklist, alongside rerunning quality evals.

Sources & references

  1. Prompting best practices: Migrating away from prefilled responses — Claude Docs