Auto mode classifier blocks tool calls while session is in bypassPermissions
Environment
- Claude Code 2.1.223 (also observed on 2.1.221)
- Native install, macOS (Darwin 25.x), Apple Silicon
permissions.defaultMode: "auto"in user settings; sessions switched tobypassPermissionsinteractively- No managed policy settings present;
disableBypassPermissionsModenot set - No
autoModesection in user settings — shipped default rules throughout
Summary
In sessions running in bypassPermissions, tool calls are intermittently refused by the auto mode classifier with toolDenialKind: "automode-blocked".
The permission-modes documentation describes bypassPermissions as skipping permission checks. If that is accurate, the classifier should not be consulted in this mode at all, and this is a bug. If instead the classifier is retained in bypassPermissions by design — the way PreToolUse hooks are — then the behavior is correct but undocumented, and the documentation should say so, because the current wording leads operators to conclude the mode is broken.
Either way the operator-visible outcome is the same: a mode chosen precisely to stop interruptions still interrupts.
Evidence
Across a 50-session window, 6 sessions ran in bypassPermissions. Four automode-blocked denials occurred inside those sessions. In each case:
- The denial entry is main-loop, not a subagent (
isSidechain: false), so this is not a subagent inheriting a different mode. - The most recent
permissionModevalue recorded before the denial — also main-loop — isbypassPermissions. - The session continues emitting
bypassPermissionsafterwards, so the mode had not been switched away and back.
One session's mode/denial sequence, with consecutive identical events collapsed:
bypassPermissions x76 -> DENIED: automode-blocked -> bypassPermissions x42
A second session shows the same shape: 46 consecutive bypassPermissions events, then automode-blocked.
The blocked calls were ordinary read-only operations, including gh pr view <n> --json number,mergeStateStatus,reviewDecision. That command matches the shipped Read-Only Operations allow rule, so the block is also hard to attribute to any specific deny rule.
Steps to reproduce
Not reliably reproducible on demand — the intermittency is part of the report. Observed conditions:
- Set
permissions.defaultModeto"auto"in~/.claude/settings.json. - Start a session, switch it to
bypassPermissions. - Run a long session with many tool calls, including
/modelswitches and/compact. - Intermittently a tool call is refused with
automode-blockedwhile the mode is stillbypassPermissions.
Denial records live in the session transcript JSONL: user entries carrying a top-level toolDenialKind, interleaved with entries carrying permissionMode.
Expected
In bypassPermissions, no permission check runs and no classifier is consulted; a tool call executes or fails on its own merits.
Alternatively, the documentation states plainly that the auto mode classifier and PreToolUse hooks both still apply in bypassPermissions.
Actual
The classifier runs and can refuse the call, producing a denial the operator explicitly opted out of.
Impact
This is the difference between an agent that can run a multi-hour unattended task and one that cannot. Long-horizon autonomous work is the use case bypassPermissions exists for, and an intermittent block halts the run at an arbitrary point, often on a trivially safe read.
Documentation suggestions (minor, separable)
skipDangerousModePermissionPrompt: truereads as though it forces bypass mode. It suppresses the confirmation dialog only. One clarifying line in the settings reference would prevent the misreading.
- Hooks override
bypassPermissions, and the permissions page does not say so. APreToolUsehook returningpermissionDecision: "ask"prompts even inbypassPermissions. That is defensible — it lets a project keep a hard safety net the operator cannot switch off by accident — but it is the first thing an operator suspects when bypass "does not work", and the remedy (reading thepermission_modefield inside the hook and honoring it) is discoverable only from the hooks reference. Suggest cross-linkingpermission_modefrom the permission-modes section.
- Denial messages do not name the rule that fired. A refusal reads "Blocked by classifier" with no rule name, and its remedy line suggests adding a Bash permission rule even when the denied call was an
Edit. Naming the matched rule — e.g. "Self-Modification" — would tell the operator what consent is missing. As it stands, the only way to find out is to runclaude auto-mode configand match the action against the rules by hand. For thesoft_denyfamily this matters a lot: those rules clear when the user names the specific change, so a named rule is directly actionable.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Adding another repro, in the desktop app this time. The classifier kept denying calls after the session had left auto mode and was reporting bypass permissions.
Environment
defaultModeorautoModeset in~/.claude/settings.jsonorsettings.local.jsonWhat happened
mcp__Claude_Browser__*). The user had given the values in chat and explicitly asked for the form to be filled and submitted.mcp__Claude_Browser__browser_batch(severalform_inputcalls) was denied every time withPermission for this action was denied by the Claude Code auto mode classifier. Reason: Blocked by fast classifier.form_inputcalls were nondeterministic. The same call with the same value, on the same tab and field, was denied once and allowed on a later turn.form_inputcalls were still denied with the same "Blocked by fast classifier" reason.Observations
claude auto-mode config, the likely match is the soft-deny Browser Input Exfil, which covers "any input into a page whose most recentnavigatewas to an external domain". That rule is written for Chrome-MCP but seems to apply to the built-in browser MCP too./permissions→ Recently denied, run in a separate terminalclaudesession, shows "No recent denials". Denials from a desktop-app session don't appear there, so the user has no way to review or retry them.Expected
After leaving auto mode, or in bypassPermissions, the classifier shouldn't run, as the permission-modes docs describe. If it does run by design, a denied call should fall back to a normal permission prompt (#92279) rather than a hard deny.
Related: #85330, #58222, #95777, #95200, #92279
Another repro, desktop app (Code tab). This started for me with 2.1.284 and has not happened on any earlier version.
Environment
permissions.defaultMode: "bypassPermissions"in both~/.claude/settings.jsonandsettings.local.jsonautoModesection at first (see test below), no managed settings,permissions.allowincludesmcp__claude-in-chrome__*get_sessionreportspermissionMode: "bypassPermissions"for the affected sessionWhat happens
Browser tool calls are denied with
Permission for this action was denied by the Claude Code auto mode classifier. Reason: Blocked by fast classifier.while the session is in bypassPermissions.Blocked calls include:
mcp__claude-in-chrome__select_browser(selecting the user's own default browser)mcp__claude-in-chrome__navigateto a public docs pagemcp__claude-in-chrome__browser_batch(typing a value into a field the user asked to change; a read-onlyjavascript_exec)mcp__Claude_Browser__preview_startfor a localhost dev server and for a localfile://pageTimeline (from local transcripts) — corrected
denied by the Claude Code auto mode classifierresult (not only the "fast classifier" wording), bypassPermissions sessions were already being denied sporadically since 2026-07-21 (2.1.215 → 2.1.266; 1–7 per day on the days it happened, reason textBlocked by classifier).Blocked by fast classifierand the frequency jumped to 5–9 denials per day (2026-09-29 → 10-01).claude-in-chrome, 11Claude_Browser(built-in browser pane).select_browserdenied; opening a docs URL in the built-in pane in the same session allowed.Likely root cause (from reading the bundled binary; the env/flag names are measured, the interpretation is mine)
bypassPermissions: tools from the built-in browser servers (Claude Browser/Claude Preview) are always re-routed toauto(classifier); tools fromclaude-in-chromeare re-routed toautoonly whenchromeClassifierFloorEnabled === true.chromeClassifierFloorEnabledisCLAUDE_CHROME_CLASSIFIER_FLOOR ?? growthbook("tengu_cowork_chrome_automode_default", false).~/.claude.jsoncache hastengu_cowork_chrome_automode_default: truewithcachedExperimentData→experimentId: "cowork_chrome_automode_default_experiment_cli", variationId: 1. So this account is in the treatment arm of an experiment that turns the Chrome classifier floor on for CLI/desktop sessions — which is what makes bypassPermissions behave differently from the permission-modes docs.CLAUDE_PREVIEW_CLASSIFIER_FLOOR=1to the bundled CLI, but 2.1.284 does not contain that env name, so it looks unrelated.autoMode.environmentdoes not helpI added an
autoMode.environmentsection to~/.claude/settings.json(keeping"$defaults") describing the routine use: operating my own logged-in accounts via Claude in Chrome, selecting my own connected Chrome browser, previewing localhost/local files.claude auto-mode configfrom the bundled 2.1.284 binary shows the new entries loaded. The sameselect_browsercall was still "Blocked by fast classifier" right after.Expected
Either bypassPermissions skips the classifier as the permission-modes docs describe (including for accounts in this experiment), or the docs say the classifier still runs in bypassPermissions for browser tools and which flag/setting governs it. I will add a follow-up here after testing the
CLAUDE_CHROME_CLASSIFIER_FLOOR/CLAUDE_CODE_AUTO_MODE_SERVERopt-outs in a fresh session.Follow-up: the opt-outs work, plus a note from the user's side
Test (fresh desktop-app session, bypassPermissions, bundled 2.1.284, 2026-10-01 03:22 UTC)
Added to
~/.claude/settings.json:Then in a new session, with no other changes:
| Step | Call | Result |
|---|---|---|
| 1 |
echoof both env vars from Bash | both0|| 2 |
mcp__claude-in-chrome__select_browser(my own default Chrome) | allowed || 3 |
mcp__claude-in-chrome__navigatetohttps://docs.zoom.us/(the exact call denied on 09-29), thenget_page_text, thentabs_close_mcp| all allowed || 4 |
mcp__Claude_Browser__preview_starton a public docs page | allowed |Zero
Blocked by fast classifier/Blocked by classifierresults. Before these two lines: 5–9 denials per day for three days on read-only browser calls. After: none so far.So for anyone hitting this:
CLAUDE_CHROME_CLASSIFIER_FLOOR=0is the switch that gets you out of thetengu_cowork_chrome_automode_defaulttreatment arm, andCLAUDE_CODE_AUTO_MODE_SERVER=0turns off the server-side fast classifier. Both are opt-outs that already exist in the binary; nothing is patched.From the user's side
I want to add this not as a bug report but as feedback, because I like this product and I want it to get better.
bypassPermissionsbehaves. I found out only by reading the bundled binary and my own~/.claude.json. The permission-modes docs still describe the pre-experiment behavior.autoMode.environmentdoes not help because the fast classifier rejects before it is consulted.What would have made this a non-event:
bypassPermissionsfor read-only calls on the user's own already-connected browser.Happy to provide transcripts or test anything else.