Claude Code Auto Mode Model: Set It and Fix Headless Sessions
How CLAUDE_CODE_AUTO_MODE_MODEL picks the client-side auto mode classifier model, why server-side auto mode ignores it, and the v2.1.302 claude -p fix.

Set CLAUDE_CODE_AUTO_MODE_MODEL in the environment Claude Code starts from and it chooses the model the client-side auto mode classifier calls when it judges each tool call. That is the entire feature. It only matters when the classifier runs on your side, through your provider and on your bill. It does nothing when auto mode uses Anthropic's server-side classifier, which the Claude Code changelog made the default in 2.1.278 for Claude API and Enterprise accounts and on Bedrock, Vertex, Foundry and gateways.
Two things trip people up. First, most accounts never hit the client-side classifier anymore, so the variable looks broken when it's simply not in the path. Second, Claude Code v2.1.302, released October 16, 2026, starts claude -p and Agent SDK sessions in default permission mode on third-party providers. Headless runs that used to inherit auto mode now need --permission-mode auto passed explicitly.
What the auto mode model variable controls#
Auto mode swaps the per-tool permission prompt for a classifier. Each tool call Claude wants to make goes to that classifier, which returns allow or block. The classifier can run in two places:
- Client-side. Claude Code sends the classification request itself, through whatever provider your session uses, with a model billed to you.
CLAUDE_CODE_AUTO_MODE_MODELpicks that model. - Server-side. Anthropic runs the classifier. The 2.1.278 changelog entry says this path does not charge for classifier overhead, and Claude Code warns when it has to fall back to the billed client-side path.
The smallest working setup for the client-side case:
export CLAUDE_CODE_AUTO_MODE_MODEL=claude-haiku-5-5
claude --permission-mode auto
Or scoped to one invocation:
CLAUDE_CODE_AUTO_MODE_MODEL=claude-sonnet-5-5 claude --permission-mode auto
Use a model ID your provider actually serves. As of October 17, 2026, the Claude models overview lists these current IDs and base prices:
| Model | Claude API ID | Amazon Bedrock ID | Base price |
|---|---|---|---|
| Claude Haiku 5.5 | claude-haiku-5-5 |
anthropic.claude-haiku-5-5 |
From $0.10 / input MTok, from $0.50 / output MTok |
| Claude Sonnet 5.5 | claude-sonnet-5-5 |
anthropic.claude-sonnet-5-5 |
$2 / input MTok, $10 / output MTok |
| Claude Opus 5.5 | claude-opus-5-5 |
anthropic.claude-opus-5-5 |
$4 / input MTok, $20 / output MTok |
| Claude Fable 5.1 | claude-fable-5-1 |
anthropic.claude-fable-5-1 |
$10 / input MTok, $50 / output MTok |
The Google Cloud, Microsoft Foundry and Claude Platform on AWS IDs match the Claude API IDs on that page. The changelog doesn't name a default classifier model for when the variable is unset, so don't assume one. If you care which model judges your tool calls, set it.
I'd start with Haiku. The models overview describes it as the model for classification, extraction and routing, and a permission classifier is exactly that kind of job. Move up only if you see allow or block decisions you disagree with.
Why it doesn't affect server-side auto mode#
The 2.1.278 entry in the changelog is the key fact. Auto mode for Claude API and Enterprise users, and on Bedrock, Vertex, Foundry and gateways, now defaults to the server-side classifier. That classifier runs on Anthropic's infrastructure. Your session never sends a classification request through your provider, so there is no client-side model to pick, and CLAUDE_CODE_AUTO_MODE_MODEL has nothing to act on.
The same release added an Auto mode server row to /status. That row is your ground truth. Run /status inside the session and read it before touching any environment variable.
If you want the client-side classifier back, the changelog lists one opt-out:
export CLAUDE_CODE_AUTO_MODE_SERVER=0
export CLAUDE_CODE_AUTO_MODE_MODEL=claude-haiku-5-5
claude --permission-mode auto
Read the scope carefully. The opt-out is listed for Bedrock, Vertex, Foundry and gateways only. The changelog doesn't offer it for direct Claude API or Enterprise accounts, so on those the model variable stays inert. The usual reason to opt out is a routing or compliance requirement: you want every request, including classifier traffic, to go through your own provider endpoint. You pay classifier overhead for that, which is what the auto mode classifier billing page covers.
Here's the decision logic as a small script, so you can sanity-check an environment before a long run. Providers the changelog doesn't name fall through to a check of /status rather than a guess:
// Which classifier path applies for a given provider and environment?
const SERVER_DEFAULT = ['claude-api', 'enterprise', 'bedrock', 'vertex', 'foundry', 'gateway'];
const CAN_OPT_OUT = ['bedrock', 'vertex', 'foundry', 'gateway'];
function classifierPath(provider, env) {
if (!SERVER_DEFAULT.includes(provider)) {
return { path: 'unknown: read the Auto mode server row in /status', modelVarApplies: 'check /status' };
}
const optedOut = env.CLAUDE_CODE_AUTO_MODE_SERVER === '0' && CAN_OPT_OUT.includes(provider);
if (!optedOut) {
return { path: 'server-side (no classifier overhead billed)', modelVarApplies: false };
}
return {
path: 'client-side (billed through your provider)',
modelVarApplies: true,
classifierModel: env.CLAUDE_CODE_AUTO_MODE_MODEL || '(unset: changelog names no default)'
};
}
const cases = [
['claude-api', { CLAUDE_CODE_AUTO_MODE_MODEL: 'claude-haiku-5-5' }],
['claude-api', { CLAUDE_CODE_AUTO_MODE_SERVER: '0', CLAUDE_CODE_AUTO_MODE_MODEL: 'claude-haiku-5-5' }],
['bedrock', { CLAUDE_CODE_AUTO_MODE_MODEL: 'claude-haiku-5-5' }],
['bedrock', { CLAUDE_CODE_AUTO_MODE_SERVER: '0', CLAUDE_CODE_AUTO_MODE_MODEL: 'claude-haiku-5-5' }],
['bedrock', { CLAUDE_CODE_AUTO_MODE_SERVER: '0' }],
['other', {}]
];
for (const [provider, env] of cases) {
console.log(provider.padEnd(11), JSON.stringify(env).padEnd(78), JSON.stringify(classifierPath(provider, env)));
}
The second line is the one that surprises people: on the direct Claude API the opt-out isn't listed, so the model variable still doesn't apply even with CLAUDE_CODE_AUTO_MODE_SERVER=0 set.
The v2.1.302 change for claude -p and the Agent SDK#
Before v2.1.302, a headless claude -p session or an Agent SDK session on a third-party provider could end up in auto mode without being asked for it. As of v2.1.302, those sessions start in default permission mode on third-party providers. Default mode means the normal permission rules apply, and anything not pre-approved waits on a prompt nobody is there to answer. In a pipeline that shows up as a job that hangs or a tool call reported as rejected.
The fix is one flag:
claude -p "Run the test suite and summarize the failures" --permission-mode auto
For the Agent SDK, set the permission mode to auto in the options you create the session with, the same way you'd pass any other session option. The default no longer does it for you on Bedrock, Vertex, Foundry or a gateway.
Interactive sessions are not what changed. If you open claude in a terminal on Bedrock and switch to auto mode as you always did, nothing is different. The change is specifically about non-interactive entry points on third-party providers. Passing the flag everywhere is the safe habit: it is a no-op where auto mode was already going to be selected, and it saves you from relying on a default that just moved.
If you run Claude Code on a server, the headless setup guide covers the surrounding pieces: authentication, output formats and where logs go. The script below prints complete command lines for the combinations discussed so far, ready to paste into a job definition:
import shlex
THIRD_PARTY = {'bedrock', 'vertex', 'foundry', 'gateway'}
def headless_command(prompt, provider, classifier_model=None):
env = {}
# v2.1.302: claude -p starts in default mode on third-party providers,
# so auto mode has to be requested. Passing it everywhere is harmless.
argv = ['claude', '-p', prompt, '--permission-mode', 'auto']
if classifier_model:
if provider in THIRD_PARTY:
# The client-side classifier only runs after opting out of server-side.
env['CLAUDE_CODE_AUTO_MODE_SERVER'] = '0'
env['CLAUDE_CODE_AUTO_MODE_MODEL'] = classifier_model
else:
print(f'# note: no documented opt-out on {provider}; classifier model ignored')
prefix = ' '.join(f'{k}={shlex.quote(v)}' for k, v in env.items())
return (prefix + ' ' if prefix else '') + shlex.join(argv)
prompt = 'Run the test suite and summarize the failures'
print(headless_command(prompt, 'bedrock'))
print(headless_command(prompt, 'bedrock', 'claude-haiku-5-5'))
print(headless_command(prompt, 'claude-api', 'claude-haiku-5-5'))
How to confirm which classifier handled a tool call#
Three checks, from cheapest to most thorough.
- The
/statusrow.Auto mode servertells you whether this session's classifier runs server-side. If it does, stop debuggingCLAUDE_CODE_AUTO_MODE_MODEL; it isn't in play. - The billed fallback warning. Since 2.1.278 Claude Code warns when it falls back from the server-side path to the billed one. If you see that warning, the model variable now governs those fallback requests.
- OpenTelemetry
tool_decisionevents. Version 2.1.301 addedclassifier_verdictandpermission_modeto those events, so you can tell a classifier decision apart from a permission rule match. WithOTEL_LOG_TOOL_DETAILS=1you also getclassifier_category, naming the built-in rule a classifier block matched. If you already export telemetry, the notes on reading Claude Code's OpenTelemetry attributes cover the surrounding fields.
The telemetry route is the only one that works for unattended claude -p runs, where nobody is around to type /status. After the v2.1.302 change it is also the fastest way to prove a pipeline really is in auto mode: look at permission_mode on the first few tool_decision events of a run.
What the client-side model choice costs#
The classifier fires once per tool call, so over a long agentic session it adds up to many short requests. When the classifier runs server-side, the changelog says there is no classifier overhead on your bill, and model choice isn't yours to make. When it runs client-side, every one of those requests is priced at the classifier model's rate.
That's why the model you pick matters. As of October 17, 2026, the models overview lists Claude Haiku 5.5 from $0.10 / input MTok and Claude Sonnet 5.5 at $2 / input MTok. For a classifier that reads a tool call and a bit of context, that gap is the difference between noise and a line item. If your session token usage already feels high, the breakdown of why Claude Code uses so many tokens explains which parts of a session the classifier overhead sits on top of.
The auto mode classifier billing page is the place to check current billing rules before you commit a team to the opt-out.
Common mistakes and gotchas#
- Setting the model variable on a server-side session. On direct Claude API, Enterprise, or any of the four third-party paths without the opt-out,
/statuswill say server-side and the variable does nothing. Check the row first. - Expecting the opt-out to work on the direct Claude API. The changelog lists
CLAUDE_CODE_AUTO_MODE_SERVER=0for Bedrock, Vertex, Foundry and gateways. It doesn't list it for the Claude API or Enterprise, so don't build a plan around it there. - Upgrading to v2.1.302 and leaving
claude -pjobs unchanged. On third-party providers those jobs now start in default mode. Add--permission-mode autoto the job, and set the SDK's permission mode to auto in code. - Exporting the variable in your shell, then running from CI, cron or systemd. Those processes don't read your interactive shell profile. Put the variable in the job's own environment, as the Python example above prints it.
- Seeing auto mode reported as not available for this model. Neither the changelog nor the models overview documents that message, so start with the two things you control: the session model and the classifier model ID. Confirm both are IDs your provider lists on the models overview; Bedrock IDs carry the
anthropic.prefix. - Auto mode not showing up where you expect. Update to the current release, open
/status, and read theAuto mode serverrow. If your permission mode isn't auto, the classifier never runs, server-side or not, and the model variable is irrelevant. - Confusing the two knobs.
--permission-mode autoturns auto mode on.CLAUDE_CODE_AUTO_MODE_MODELonly chooses the model when the classifier happens to run client-side. One doesn't imply the other.
Quick reference#
| Setting | What it does | Where it applies |
|---|---|---|
--permission-mode auto |
Starts the session in auto mode | Any claude or claude -p run; required on third-party providers for -p and the Agent SDK as of v2.1.302 |
CLAUDE_CODE_AUTO_MODE_MODEL |
Picks the client-side classifier model | Only when the classifier runs client-side |
CLAUDE_CODE_AUTO_MODE_SERVER=0 |
Opts out of the server-side classifier | Bedrock, Vertex, Foundry and gateways, per the 2.1.278 changelog entry |
/status |
Shows the Auto mode server row |
Interactive sessions |
OTEL_LOG_TOOL_DETAILS=1 |
Adds classifier_category to tool_decision events |
Sessions exporting OpenTelemetry, 2.1.301 and later |
Before you file a bug that the auto mode model isn't being used:
- Confirm the session is actually in auto mode, with the flag or by switching in the session.
- Read the
Auto mode serverrow in/status. Server-side means the variable is inert by design. - On Bedrock, Vertex, Foundry or a gateway, set
CLAUDE_CODE_AUTO_MODE_SERVER=0if you need the client-side path, then setCLAUDE_CODE_AUTO_MODE_MODEL. - Use a model ID from the models overview that your provider serves.
- For headless runs after v2.1.302, add
--permission-mode autoand verify withpermission_modeontool_decisiontelemetry events.
Quick answers
Which model does the Claude Code auto mode classifier use?
When the classifier runs server-side, which is the default for Claude API and Enterprise accounts and on Bedrock, Vertex, Foundry and gateways since 2.1.278, Anthropic runs it and you don't choose. When it runs client-side, CLAUDE_CODE_AUTO_MODE_MODEL picks the model; the changelog doesn't name a default for when it's unset.
Why does auto mode say it isn't available for this model?
The changelog and the models overview don't document that message. Start by confirming that both your session model and any classifier model you set are IDs your provider serves, remembering that Bedrock IDs carry an anthropic. prefix.
Why did auto mode stop working in my claude -p job?
Claude Code v2.1.302, released October 16, 2026, starts claude -p and Agent SDK sessions in default permission mode on third-party providers. Pass --permission-mode auto explicitly, or set the SDK's permission mode to auto.
Does CLAUDE_CODE_AUTO_MODE_MODEL change what I'm billed for auto mode?
Only on the client-side path, where each classification request is billed at the chosen model's rate. The server-side classifier doesn't charge classifier overhead, and Claude Code warns if it falls back to the billed path.
How do I check whether auto mode is using the server-side classifier?
Run /status in the session and read the Auto mode server row. For unattended runs, look at the classifier_verdict and permission_mode fields on OpenTelemetry tool_decision events, added in 2.1.301.
Did this solve it?
One tap. No account.
Sorry about that. What was missing?
from 0 readers
Saved you an hour? Send a tip.
USDC or ETH on Base, Ethereum, Arbitrum and more. Keeps the notes free and the examples running.
Network
0xc783bc5c3fa14cEC3f09A22284bC91C5AF0d59e1
On a computer? Scan the code with your phone wallet, or copy the address.
Pick the network your wallet or exchange uses. USDC works on all six; ETH on Base, Ethereum, Arbitrum and Optimism. Don't send on Tron or Solana: this address doesn't exist there. Tips are optional and unlock nothing; every guide stays free.
Discussion
Start the discussion
Next note