Dev.to AI 🤖 Ai 👁 0 📖 4 min read

The error told you to delete one line. Deleting it changed every answer.

A breaking change that fails loudly, and a fix that changes your product silently. The error told you to delete one line. Deleting it changed every answer your product gives. What changed Anthropic's API ver

A breaking change that fails loudly, and a fix that changes your product silently.

The error told you to delete one line. Deleting it changed every answer your product gives.

What changed

Anthropic's API version 2026-10-21 removed temperature, top_p and top_k from the Messages API. Not deprecated with a grace period. Removed.

The migration guide states it plainly:

In 2026-10-21, a request that sends temperature, top_p, or top_k returns a 400 error, even at the parameter's default value.

So this is a loud failure. Your request breaks, the error names the parameter, and you know exactly what to do.

That part is fine. Loud failures get fixed.

The part that is not loud

The fix is to delete the parameter. The guide then tells you what happens next:

Without these parameters, a request samples with their defaults, including a temperature of 1.0, the same as a 2023-06-01 request that leaves them out.

Your line said 0.0. You deleted it. You are now sampling at 1.0.

And for the models where that difference was real:

On models that accept other values, such as Claude Sonnet 4.6, a request that lowered temperature for more consistent output loses that effect. No other setting replaces it.

No other setting replaces it. That sentence is the whole article.

The sequence, as it actually plays out

# Before: 2023-06-01, pinned low for a structured extraction task
resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    temperature=0.0,          # <- deliberate. consistency matters here.
    messages=[{"role": "user", "content": prompt}],
)

You bump the SDK. The call fails with a 400 — something to this effect (exact wording illustrative; the documented behaviour is a 400):

anthropic.BadRequestError: 400 - temperature is not supported
in API version 2026-10-21

You do the obvious thing:

# After: the 400 is gone
resp = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": prompt}],
)

Green. Tests pass. Ship it.

What actually happened:

  1. You upgraded. A 400 appeared. The error named the parameter.
  2. You deleted the parameter. The 400 went away.
  3. Your tests passed — because your tests assert on shape, not on distribution.
  4. Your product's output variance is permanently higher, and nothing in your pipeline said so.

Step 2 is where it happens. The fix that silences an error is not the fix that preserves behaviour. And an error message is written to be silenced — that is its entire job.

Why your test suite will not catch this

Most LLM test suites look like this:

def test_extraction():
    out = extract(SAMPLE_INVOICE)
    assert out["invoice_no"] == "INV-2291"
    assert isinstance(out["line_items"], list)
    assert out["total"] == 118000

That is a shape and value assertion on one sample. At temperature=0.0 it was close to a deterministic check. At 1.0 it is a sample from a distribution that now happens to pass.

It will keep passing. Right up until the day it does not, on a customer's document, in production, with no code change to blame.

What catches it instead:

def test_extraction_is_stable():
    runs = [extract(SAMPLE_INVOICE) for _ in range(20)]
    distinct = {json.dumps(r, sort_keys=True) for r in runs}
    # not "did it work once" but "does it work the same way"
    assert len(distinct) == 1, f"{len(distinct)} distinct outputs in 20 runs"

Slower. More expensive. The only thing that would have told you.

To be fair to the guide

The escape hatch is documented:

If a request relies on a non-default value, either stop sending the parameter, or keep that request on 2023-06-01.

It is right there. It sits in the paragraph most people stop reading after sentence one, immediately below the instruction that fixes their build.

That is not a documentation failure. It is a reading failure, and it is extremely common: when an error message and a fix appear in the same paragraph, the rest of the paragraph does not get read.

The discipline

When a breaking change hands you a fix, ask what the fix changes. "Remove it" is a behaviour change wearing an error message.

Treat sampling settings as product config, not tuning knobs. Write down which of your outputs depend on low variance — structured extraction, classification, anything feeding a downstream parser — and which genuinely do not.

Test distribution, not shape. Run one prompt 20 times and diff them. A schema check will never catch this.

Record the API version your behaviour was measured against, beside the measurement. An eval result without its API version is an incomplete artefact.

Two hard rules

An error you silenced is not a bug you fixed.

If removing a setting is the official fix, that setting was doing something.

While you are in there

From the same source, one dated item worth putting in a calendar:

Deprecated model Retires Recommended replacement
claude-sonnet-4-5-20250929 30 November 2026 claude-sonnet-5-5

And the lifecycle definition, verbatim: "Retired: The model is no longer available for use. Requests to retired models fail."

That one, at least, is not silent.

Anthropic also states it provides "at least 60 days' notice before model retirement for publicly released models" — and the console has a usage export that breaks your traffic down by API key and model, which is the fastest way to find out whether a deprecated model is still in your path.

Honest limitation

I am reading Anthropic's own migration guide and model-deprecation page, and every quote above comes from them.

I have not measured the variance change on a production workload. How large it is depends entirely on your prompts: a tightly constrained extraction prompt with a rigid schema may move barely at all, while an open-ended generation task may move a lot. The point is not the size of the effect. The point is that the change happened and nothing told you.

Checkable references

  • "Migrating to API version 2026-10-21" — Claude platform docs
  • "Model deprecations" — Claude platform docs

One open question

When you removed temperature to clear that 400 — did anyone measure the output before and after?

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.