Output handling and debuggingThe 400 catalogue, and two doc pages that will break you
No narration yet
Module 3, Lesson 225 min

The 400 catalogue, and two doc pages that will break you

Something changed in how the current models handle configuration they do not like, and it changed in a direction that is good engineering and bad for your existing code.

They reject instead of accommodating. Old behaviour was to ignore an unsupported field, clamp an out-of-range number, or quietly drop a feature. Current behaviour is a 400. Here is the catalogue.

Prefill on the final assistant turn

You know the trick. You seed the assistant's response with an opening brace or the first word, and the model continues from there. It was the standard way to force a format before structured outputs existed.

Assistant prefill on the LAST assistant turn now returns a 400 on Claude 4.6 and later.

The nuance that matters: prefill earlier in the conversation is still fine. This is not "prefill is banned". It is specifically the final assistant turn, the one you are seeding to steer the next generation.

Teach yourself the disagreement rather than smoothing it over. The API behaviour is what runs, so the API wins. The migration path is documented, under Migrating away from prefilled responses in the Output and formatting section, which is exactly where you would hope it lives and exactly where nobody looks because they are reading the older page that a search engine surfaced first.

Extended thinking configuration

Second entry. The explicit thinking config, thinking.type: "enabled" with a budget_tokens value, is deprecated on 4.6 and 400s on 4.7 and later. Adaptive thinking replaced it.

The trap here is that budgets normally clamp. You set 50,000 against a model that allows 30,000 and you expect to get 30,000. Not any more. Setting the field at all is the problem, not the value in it.

Sampling parameters on Opus 4.7+

Third. temperature, top_p and top_k return a 400 on non-default values for Opus 4.7 and later.

Go and look at your codebase right now. Somebody set temperature: 0 five years ago for determinism, it was correct at the time, it has been copy-pasted into every client since, and it is a hard failure the moment you point it at one of those models.

This is the highest-frequency real-world instance in the list, because pinning temperature to zero is close to universal in production code.

Citations plus structured outputs

Fourth, and we met it last lesson. Citations together with structured outputs returns a 400. Two features, each fine alone, rejected in combination.

The pattern to carry into the exam

Four entries, one shape. When a question describes an unsupported configuration and offers you "silently ignored", "clamped to the maximum", "a warning in the response", and "a 400", the current-generation answer is the 400.

It is the same trade as switching a service from lenient parsing to schema validation at the boundary. Everyone agrees the strict version is correct, and everyone discovers on the day of the switch how much code was quietly relying on the leniency. The other three options are all tempting for the same reason: they describe how APIs used to behave, and how a forgiving API is supposed to behave. Forgiving is exactly what got removed.

Practice

Try it yourself

Quiz

Prefill on current models

You seed the assistant's reply with an opening brace to force JSON, as the docs page you are reading recommends. You are on Claude 4.6. What happens?

Quiz

Extended thinking

Inherited code sets thinking.type to enabled with a budget_tokens value. You are moving it to Claude 4.7. What do you expect?

Quiz

Predict the response

One request, four fields, targeting Opus 4.7. Nothing here is malformed and the schema validates.

// MODEL is pinned to Opus 4.7
await client.messages.create({
  model: MODEL,
  temperature: 0,
  max_tokens: 4096,
  messages: [{ role: "user", content: prompt }],
})

What comes back?

Recall

Sampling parameters on Opus 4.7+

Three parameter names, one behaviour, one version boundary. This is the entry in the catalogue most likely to be sitting in code you already own.

What is the current behaviour of temperature, top_p and top_k on Opus 4.7 and later?

Recall

When the docs disagree with the API

Two sources, one contradiction, and the interesting part is not only which one wins. Note what the losing source gets wrong, because it understates rather than simply being stale.

Two documentation pages recommend prefill, but the API 400s on it. How do you resolve the conflict, and what does each source actually tell you?

Check

Grep your own codebase

Ten minutes, one repository, no network. Four searches: a trailing assistant message in a messages array, thinking configuration with a token budget, temperature or top_p or top_k, and citations set alongside a structured output.

You should see

You have a written list with a yes or no against each of the four catalogue entries, and for each yes you know which call sites are affected and which models they point at. A no you actually grepped for is worth a great deal more than a no you assumed, because three of these four were correct practice when the code was written.