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.
Four facts you can quote
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.
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.
2026-08-28
The same changelog also fixed effort … is not supported when thinking is disabled. One upgrade, two surfaces.
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
Claude Code already had SessionStart, Stop, tool events. Enterprises use them for audit and block.
Added PreModelSwitch and PostModelSwitch hook events (block, confirm, or annotate a model switch).
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.
Related
Claude Code hooks automation
Existing SessionStart / Stop events; this page only adds the model-switch slice.
Claude Code slash commands
/model and the picker are one PreModelSwitch trigger.
Anthropic Agent Skills
A different official extension surface; do not mix names with hook events.
Reading of Claude Code 2.1.251 changelog, not a promise about unpublished payload fields. QCode does not run client hooks and does not bypass org model policy.