Claude Code now allows controlling model changes with hooks

Claude Code 2.1.251 adds hooks to control model changes before and after they occur, and that turns model switching into an auditable workflow decision.

The short phrase from the official changelog, published on August 28, 2026, is: “Added PreModelSwitch and PostModelSwitch hook events”.

But the useful reading for teams isn’t “Claude Code added two more hooks”. The useful reading is that the model stopped being only an individual developer’s preference. In a long session, with prompt cache, sub-agents, permissions, Remote Control, SDKs and possible model gateways, switching models can impact cost, policy, performance, traceability and which provider receives the data.

That’s where PreModelSwitch and PostModelSwitch matter.

The first lets you intervene before Claude Code applies a model change requested by a person or a client. It can block the change, ask for confirmation or show cost information before proceeding. The second runs after the session has already switched models and is used for auditing, logging or injecting specific guidance for the new model.

For teams already using Claude Code seriously, this isn’t cosmetic. It’s governance.

And for teams in Latin America, where many organizations combine cloud accounts, security restrictions, project budgets and heterogeneous development tools, that governance is starting to become a concrete operational advantage.

How Do You Control Model Changes in Claude Code?

To control model changes in Claude Code, you use PreModelSwitch as a decision point before the change and PostModelSwitch as an audit or adaptation point after the change.

The official documentation places PreModelSwitch before Claude Code applies a requested model change. That event can block the change. It can also return a permissions decision equivalent to allow, deny or ask the user.

PostModelSwitch, on the other hand, runs after the session has already changed models. It can’t prevent anything because the change already happened, but it can add context for the next request, log evidence or apply instructions specific to the current model.

The difference seems small, but it defines two distinct responsibilities:

  • PreModelSwitch is preventive policy.
  • PostModelSwitch is observability and adaptation.

If a team wants to prevent certain projects from using a retired, expensive or unapproved model, the control belongs in PreModelSwitch. If it wants to log that a session moved from a cheap model to a stronger one, or give operational instructions to the new model, the natural place is PostModelSwitch.

That pattern looks a lot like what’s already happening with tools, commands and MCP: agents need intervention points around their actions, not just general prompts at the beginning of the session.

What Is Claude Code and Why Does This Change Matter?

Claude Code is Anthropic’s development agent for working on repositories, running tools and sustaining programming sessions from CLI, IDEs, SDKs and remote flows.

At yoDEV we’ve been following that movement across several layers: sessions that talk to each other across machines with ListAgents and SendMessage, self-hosted runners to execute sessions on your infrastructure, local plugins, dynamic workflows and SDKs to build your own copilots.

That context matters because PreModelSwitch doesn’t land on a simple product. It lands on a surface where the agent can work for a long time, move context between tools, delegate to sub-agents, receive instructions from external clients and operate on real repositories.

When the agent works five minutes on a trivial task, switching models might feel like a convenience. When it works inside a team flow, the model change touches more serious questions:

  • Is this model approved for this repository?
  • Does the change break a cost policy?
  • Do we lose a warm cache that already had context loaded?
  • Does the new model need different instructions?
  • Who asked for the change: the person, the picker, /config, fast mode, the SDK or Remote Control?
  • Is the transition logged for audit?

Claude Code 2.1.251 puts those questions inside the hook cycle.

Why Can Switching Models Cost More Than It Seems?

Switching models can cost more than it seems because a long session can have a lot of context and a warm prompt cache that gets lost when you switch destinations.

The PreModelSwitch documentation exposes fields designed precisely so the hook can show the cost before the change happens. Among them are context_tokens, prompt_cache_warm, cache_ttl, estimated_cache_write_usd and pricing.

That list tells a clear story.

Claude Code doesn’t just tell you “you’re going from one model to another”. It also gives the hook data about how many tokens might be resent, whether the current cache is likely still warm, how long that cache lives and how the cost in dollars of writing that context to the destination model’s cache was estimated.

The documentation clarifies that that cost is an estimate, because the server might not need to recache all the context. Still, for a team it’s signal enough to make better decisions.

A typical case: a session has hours of conversation, file reading and tool results. Someone switches from a cheaper model to a stronger one just before a small question. Without control, that transition can resend a mass of context that wasn’t needed for the task. With PreModelSwitch, the team can ask for confirmation when estimated cost crosses a threshold, block changes from non-interactive surfaces or simply show a warning.

This turns cost into part of workflow design.

It’s not about scolding the developer for choosing a strong model. It’s about distinguishing when the strong model adds value and when the change happens out of inertia, habit or overly generous automation.

What Model Policies Can a Team Apply?

A team can use model change hooks to apply approved model lists, retire obsolete models, ask for confirmation on high costs and log changes made from SDKs or Remote Control.

The official documentation shows that PreModelSwitch fires for changes requested from /model, from the model picker, from configuration, when activating fast mode if that changes the model, or from set_model requests and model changes sent by Agent SDK hosts or Remote Control.

That range matters. If control only covered the interactive UI, it would be a local convenience. By covering SDK and Remote Control, it becomes a piece for environments where Claude Code is embedded in broader flows.

Some reasonable policies:

  • Block retired or unapproved models.
  • Ask for confirmation when estimated_cache_write_usd exceeds a threshold.
  • Allow changes to cheap models without friction and ask for approval for premium models.
  • Deny model changes from non-interactive automations.
  • Log from_model, to_model, source and pricing in an internal system.
  • Show a warning when prompt_cache_warm is true and the change means losing that advantage.

The fine part is not coding policies that are too brittle.

Claude Code matches matchers against canonical model names. The documentation also warns that, if it can’t determine a canonical name for the destination—for example behind a gateway that uses its own IDs—it runs all PreModelSwitch hooks without relying on the matcher. That’s why a robust policy should check the to_model field received by the hook, not rely only on the matcher.That detail is exactly the type of edge that makes these hooks relevant for teams, not just for advanced users.

What’s the difference between blocking, asking, and annotating?

Blocking, asking, and annotating are three distinct levels of operational control over model changes.

Blocking is the strong decision. In Claude Code, a hook can cancel the change with a block decision or with the documented exit code for blocking actions. It’s the right choice when the model isn’t approved, the route violates a policy, or automation attempts a change the team doesn’t want to allow.

Asking is useful when the change might be reasonable, but deserves human confirmation. For example, upgrading to a more expensive model with 180,000 context tokens might be fine if the session is resolving a complex migration. It might also be unnecessary if the person just wants a short answer. Confirmation returns context to the human before spending.

Annotating is the least intrusive mode. A hook can display or add information without blocking the transition. Cost warnings, audit notes, or follow-up instructions for the new model fit here.

The operational nuance: ask only makes sense where Claude Code can show an interactive confirmation. The documentation indicates that on non-interactive surfaces like -p, /config, or set_model requests, that decision is treated as a denial. For automated workflows, it’s better to design explicit policies: allow or deny, don’t rely on a question no one will see.

Why does PostModelSwitch matter if it can’t block?

PostModelSwitch matters because many model changes aren’t requested by the person and should still be visible to the team.

The documentation says PostModelSwitch runs after requested changes, automatic changes like fallbacks, entries or exits from certain modes, and model restoration when resuming a session. It also clarifies it doesn’t run when a fallback chain substitutes the model for just one turn without changing the session’s model.

That behavior makes it useful for audit.

If a session changed models via automatic fallback, the team might not have been able to block it with PreModelSwitch, because it wasn’t a user or client requested change. But they can log it afterward. In environments with compliance, internal billing, or quality analysis, that difference between “requested model” and “model actually used by the session” isn’t minor.

It also serves operational instructions. A team might want certain models to receive additional context: delegate implementation to sub-agents, stick to planning, avoid expensive tool calls, or leave a stricter review note. PostModelSwitch can add that context to the next request after the change.

It doesn’t replace CLAUDE.md or project rules. It works as a dynamic layer that depends on the active model.

What does this have to do with permissions and security?

It has to do with permissions and security because the same release that adds model-change hooks also fixes several permission, route, and settings edges.

Claude Code 2.1.251 didn’t arrive with just PreModelSwitch and PostModelSwitch. The changelog also mentions fixes for cases where file tools could follow a changed symlink within the working directory after the permissions check, plugin commands could point outside the plugin directory, workflows could read paths before the permissions check, and Grep/Glob didn’t apply certain denial rules on paths reached by symlinks.

There are also adjustments around tracing, raw API body logging, and settings behavior under higher scopes.

The underlying signal is clear: Claude Code is moving into a zone where edges matter. It’s not enough for the agent to be capable. It has to be operable under constraints.

This fits with a broader conversation we’ve also seen in other tools: code agents need sandboxing, not just good prompts, and command approval should model capabilities, not do shallow matching.

Model hooks are another part of the same architecture.

The model decides how the agent reasons. The tools decide what it can touch. Permissions decide what it’s allowed to execute. Cache and the gateway decide how much it costs and where context travels. If any of those layers change without visibility, the team loses control.

How should a team get started with these hooks?

A team should start with a small policy: log all model changes, ask for confirmation when context is large, and block only explicitly unapproved models.

That approach avoids two bad extremes. On one side, letting each session change models without traceability. On the other, creating a policy so rigid that developers disable controls to get work done.

A practical first pass could separate three goals:

  1. Visibility: log from_model, to_model, source, context_tokens, prompt_cache_warm, estimated_cache_write_usd, and pricing.
  2. Cost: ask for confirmation when the estimated cost of re-caching context is high or when cache is warm.
  3. Policy: block retired, unapproved, or repository-incompatible models.

After a week of real use, the team can look at evidence instead of debating preferences:

  • Which models actually get used.
  • From which surfaces model changes are requested.
  • How many changes happen with cache warm.
  • How many confirmations were useful.
  • Which automations try to change models.
  • Which repositories need different rules.

Good governance doesn’t start with a perfect matrix. It starts by making real behavior visible.

What’s the caveat with Claude Code 2.1.251?

The caveat is that these details have high decay risk: model names, status line fields, hook semantics, gateways, and config routes can change fast.

As of publication on September 1, 2026, the official documentation marks PreModelSwitch and PostModelSwitch as available since Claude Code v2.1.251. The changelog already shows a later version, 2.1.252, released August 31, 2026, with additional fixes. That doesn’t invalidate the 2.1.251 change, but it does confirm the release train moves fast.

That’s why it’s worth treating this note as a judgment guide, not a frozen recipe. Before copying a policy to production, check the official hooks documentation and the current changelog.

The durable part is the pattern.

Code agents are no longer a chat box that suggests functions. They’re runtimes that execute tools, consume context, use cache, delegate work, connect via SDK, and can change models within a live session.

In that world, “which model do we use” isn’t an aesthetic preference.

It’s an operational decision.

And Claude Code 2.1.251 just gave teams an explicit place to control it.