Switching models breaks things in two distinct classes, and both are worth naming precisely, because they fail differently and you catch them differently.
A model upgrade presents as trivial — a single string changes and the system ships. The two failure classes that follow are recoverable, but only if the audit looks where the failure actually lives, which is almost never the model itself.
The first class: behavioral drift
Few-shot examples, formatting instructions, and voice calibrations are not portable. A prompt tuned to coax one model into a behavior can over-trigger on a more literal, more steerable successor, or under-trigger where the older model needed heavy coaxing and the new one does not. The prompt text is still valid input — nothing errors — so the failure surfaces as an unexpected shift in output rather than an exception in the logs. Anthropic’s own guidance is to re-tune rather than port, and to validate the re-tuned prompt against an evaluation set instead of assuming the old wording lands the same way.
The trap is that behavioral drift is invisible to the smoke test. Standard prompts pass. The differences that matter concentrate in the edge cases — the malformed input, the ambiguous instruction, the long-context tail — which is exactly where a demo does not look and a production workload lives.
The second class: capability and platform gaps
The second class is harder to reason about because it hides behind a false intuition: that a model’s capabilities travel with the model. They do not. A feature is available as a function of two variables — the feature and the platform it is deployed on — and neither one is the model name. Three worked examples make the shape of the problem concrete; treat the model versions in parentheses as illustrations that will age out, not as the lesson.
The thinking-mode contract changes shape between generations. How reasoning is requested is a contract term the target model validates. The fixed-budget form — a manually set token budget for thinking — gives way to adaptive thinking, where the model decides how much to reason based on an effort signal. On newer models the old shape does not degrade gracefully; it is removed, and a request carrying the deprecated fixed-budget parameter returns a hard error (e.g., manual extended thinking is no longer accepted on Opus 4.7 and later). A team that designed around a fixed thinking budget discovers this not as a subtle regression but as a 400.
Context defaults flip, and the enabler becomes the liability. A capability can be gated behind a beta header on one generation and shipped as the default on the next. The 1M-token context window is the worked case: it was opt-in through a beta header on an earlier generation, then graduated to the default — no header, standard pricing — on current models, and the beta header that once enabled it was retired for the older models entirely. The migration lesson is counterintuitive: an audit checks headers for removal, not only addition. A header a client sends for backward compatibility can be the thing that breaks the request.
Server-tool availability is scoped to the platform, not the model. This is the gap most likely to design an architecture into a corner, because it is fully orthogonal to the model chosen. The same model gains or loses a server-side tool depending on where it runs. Web search is the clean example: it is available on the Claude API, Claude Platform on AWS, and Microsoft Foundry; Google Cloud offers the basic search only, without dynamic filtering; and it is not available on Amazon Bedrock at all. Design an architecture around a server tool, then discover the target deployment does not serve it, and the model choice was never the issue.
The move: audit against a contract, not a memory
Here is the part that makes this durable rather than a changelog to re-read every release. The instinct is to maintain a mental — or worse, a wiki — table of which model does what on which platform. That table is stale the day a new model ships, and by next quarter there will be another dozen. The table is tribal knowledge, and tribal knowledge is the thing enterprise architecture is supposed to eliminate.
The alternative is already there: the platform exposes capability as a machine-readable contract. The Models API returns, for every available model, its input and output limits and a structured capability object, and the platform documents feature availability per platform in an addressable matrix. That turns the audit from a human act of recall into a query the architecture runs at deploy time. You do not ask an engineer whether the target supports a feature; you ask the capability contract, and you fail the deploy if the answer is no. This is the same principle as generating a pipeline against a data contract — the value is not in knowing the answer, it is in the answer being structural, checkable, and impossible to skip.
The second contract is the eval suite. A migration without eval results is an assertion of behavioral equivalence that has not been verified. The capability contract tells you the target can run the architecture; the eval contract tells you it runs it correctly, and it is the only instrument that catches behavioral drift in the edge cases where it actually lives.
The checklist: run it every time
Three steps, ordered so the cheapest question comes first.
Before any upgrade, ask what is failing that the new model is expected to fix. The answer usually reveals a prompt issue, a capability gap, or an expectation mismatch — every one of which is cheaper to fix than a migration, and none of which a new model reliably fixes on its own.
Does the architecture depend on any feature — a thinking mode, a context size, a server tool — that the target model or platform does not serve? Query the capability contract rather than trusting the model name, and check the per-platform availability matrix, not memory of it.
Re-tune deliberately against the new baseline, then run the golden set. Match on observed behavior, not on the label; the differences that end migrations surface in the edge cases, not the standard prompts.
You do not migrate a model. You migrate the contracts a model operates against — the capability contract that says what will run, and the eval contract that says whether it runs correctly. A migration keyed to a model name is a bet on tribal knowledge that expires the next time a model ships.
A migration keyed to those two contracts is a structural property of the architecture, and it survives the lineup churning underneath it. The model is the variable. The contracts are the constant, and the constant is what you govern.
