Engineering · Claude Code hooks

PreModelSwitch
From 2.1.251: block / confirm / annotate a model switch

Claude Code 2.1.251 (2026-08-28) adds PreModelSwitch and PostModelSwitch hooks. Changelog: block, confirm, or annotate a model switch. SessionStart resume hooks now also receive session staleness and estimated re-cache cost. These are official hook events, not instructions to rewrite HTTP headers or impersonate another client.

#PreModelSwitch#PostModelSwitch#2.1.251#block / confirm / annotate

Four facts you can quote

PreModelSwitch

The event name before the switch

Changelog pairs it with PostModelSwitch. It runs before a switch from /model, the picker, the SDK, or a resume.

block / confirm / annotate

Three official actions

Deny cancels the switch; ask requires confirmation (refused in headless); annotate injects context for the next request. Exit code 2 can also block. That is product hook semantics.

2.1.251

2026-08-28

The same changelog also fixed effort … is not supported when thinking is disabled. One upgrade, two surfaces.

re-cache cost

New resume fields

SessionStart resume hooks now receive session staleness and the estimated re-cache cost. When a model switch invalidates cache, that is an observable cost signal, not a billing bypass.

SessionStart never saw a mid-session /model

Existing hooks guides cover Stop, SessionStart, tool events. Before 2.1.251 a mid-session /model or picker change had no matching pair of hooks. PreModelSwitch is that gap: policy, audit, and prompts can hang off the switch itself instead of only running at session start.

The picker can also set per-session effort

Same release: the model picker can set effort and an ultracode flag for the session; /effort now remembers a default per model. The “next model” PreModelSwitch sees may carry effort. Observe the request. Do not rewrite Originator-style client identifiers.

Timeline

Existing hooks

Claude Code already had SessionStart, Stop, tool events. Enterprises use them for audit and block.

2026-08-28 · 2.1.251

Added PreModelSwitch and PostModelSwitch hook events (block, confirm, or annotate a model switch).

After you upgrade

Trust your local changelog and hooks docs. Payload fields follow the schema of the version you run. This page does not invent unpublished headers.

Confirmed vs misread

Confirmed

Event names, block/confirm/annotate, same path as /model and the picker, resume staleness and re-cache cost: 2.1.251 changelog, rechecked 2026-08-30.

Misread

“Use the hook to forge another model id at the gateway” — the subject is Claude Code’s own switch flow. This page states official events; it does not describe rewriting headers or originator to change a catalog. “Ask pops a window in headless” — changelog: ask refuses in headless.

Start hooks vs switch hooks

SessionStart: session open / resume

Inject repo rules, check the workspace. From 2.1.251 resume also carries staleness and re-cache estimate. It does not see a mid-session /model.

PreModelSwitch: before every model change

“This repo must not move to that tier,” “confirm before switching,” “annotate a constraint for the next model.” PostModelSwitch records after the fact.

How official hooks attach (observation)

Upgrade to 2.1.251+, register PreModelSwitch / PostModelSwitch from the Claude Code hooks docs. Changelog actions: block, confirm, annotate. This page does not provide steps to forge model ids, rewrite HTTP headers, or bypass org model policy. If policy should stop a switch, use official deny / exit 2.

QCode does not run these hooks

PreModelSwitch runs inside the Claude Code client. QCode is a model API. Whichever sold id is actually hit after the switch follows the model field you send and the upstream catalog. For your own API, use an already-provisioned key at official price × service fee.

FAQ

When does PreModelSwitch fire?

Public notes include /model, the picker, SDK, and resume-caused switches. Trust the event table in the hooks docs for your version.

Block vs confirm?

Changelog: deny cancels; ask confirms, and refuses in headless. Annotate does not block; it adds context.

Same as the 2.1.251 effort fix?

No. The other line that day is the 400 for xhigh/max + thinking off. Hooks are events; effort is a parameter combo.

Can a hook make the gateway think I am another client?

This page does not describe rewriting client identifiers or originator. Hooks observe and constrain Claude Code’s internal model switch.

Is resume re-cache cost a bill?

Changelog: estimated re-cache cost, for hook decisions. Actual charges still follow tokens and official prices, not that field as its own ledger.

Does QCode forward these hooks?

No. Hooks are client lifecycle. The API only sees the Messages / Completions you send.

Sources

Claude Code changelog 2.1.251 (2026-08-28): Added PreModelSwitch and PostModelSwitch hook events (block, confirm, or annotate a model switch); SessionStart resume hooks now receive session staleness and the estimated re-cache cost. code.claude.com/docs/en/changelog. Rechecked 2026-08-30.

Model switches can have official hooks; billing still follows sold ids

PreModelSwitch is a Claude Code client event. For API access, official price × service fee on models that are sold.