Auto mode: let a classifier block fall back to a permission prompt instead of a hard deny

Status Open
Reported on v2.1.261
Maintainer reply None cached
Activity 3 comments · opened Sep 5, 2026

Problem

In auto mode the classifier has two outcomes: allow or block. When it blocks, the model receives automode-blocked and cannot recover. In practice it then tells the user "run these commands yourself in the terminal", which defeats the purpose of the session.

Concrete case (Claude Code 2.1.261, desktop app): I explicitly asked to release a package. The model prepared everything, then ran

git push origin develop v0.42.0

The classifier blocked it (tag push = PyPI publish). The action was exactly what I had requested; I would have confirmed it in one click. Instead I got three commands to paste into a terminal.

Workarounds today, and why they are not enough

  • permissions.ask rules take precedence over the classifier and prompt. But they need a pattern written in advance for every risky command shape (git push origin v* did not match git push origin develop v0.42.0). The classifier already identifies the risky action at runtime; the rule duplicates that judgment statically.
  • A PreToolUse hook returning permissionDecision: "ask" has the same limitation.
  • /auto-mode-setup steers the classifier's judgment, but a block still ends in a hard deny.

Request

Give the classifier's "block" outcome a configurable disposition, for example:

"permissions": { "autoModeOnBlock": "ask" }

with values deny (current behaviour, default) and ask (show the ordinary permission prompt with the classifier's reason attached). Alternatively, or in addition, a button on the block notification: "Ask me instead" / "Allow once".

Why it matters

  • The user is present in an interactive session; a prompt costs one click, a hard deny costs a context switch and manual retyping.
  • The classifier's reason is already computed; surfacing it in the prompt makes the decision better informed than a static ask rule.
  • Unattended runs keep deny as default, so nothing changes for them.

View original on GitHub ↗

3 Comments

simondambe · 1 month ago

Datapoint on 2.1.261 (macOS, interactive session, user at the keyboard), plus three reasons the hard deny costs more than the click you didn't get.

Posting this comment was itself blocked. The session that drafted it was in auto mode. I asked it to post, reviewed the text, approved it; gh issue comment on this issue was then denied with Blocked by classifier and no prompt offered, so I ran the command by hand. An explicitly requested, reviewed and approved outbound action, blocked with no approval path, on the issue asking for an approval path.

The deny blocks its own remedy. The documented fix for a classifier denial is an allow rule — but writing .claude/settings.local.json is itself classifier-gated, so the file that would unblock the action cannot be edited from inside the session that needs it. An earlier session finished with a rewritten settings file staged elsewhere and a copy command to run by hand in a separate terminal. (Related: #88330.)

The block ignores the payload and judges the wrapper. My largest false-positive group was nested commands: an outer transport or exec wrapper that looks high-risk, with an inner payload that is provably read-only — explicitly constrained to read-only, reading a single value, touching no data. Every one blocked. The classifier stops at the outermost token and never reaches the part that determines the actual risk. I was present and would have approved each in a single click.

The permissions.ask workaround is weaker than the issue states. Beyond needing every risky command shape written as a pattern in advance, ask rules matching shell operators do not fire in auto mode at all — #85098, reproduced by a maintainer, still open. So for any compound or redirected command the pre-written-rule escape hatch is unavailable too.

On the shape of the fix, autoModeOnBlock: "ask" covers it. Two things worth putting on the record.

On the adjacent classifier-unavailable path, the product's own instruction to the model is to "stop and tell the user that auto mode could not evaluate it, and suggest running this action outside auto mode (switch back to the default permission mode) or starting a fresh session."

And when you take that advice, the Bash permission prompt you land on in default mode reads Tip: auto mode handles these prompts for you — choose "switch to auto mode" below, with a one-keystroke option to do it. The tip is unconditional — it has no idea the command you are approving is one auto mode just refused. So the documented remedy for a classifier block is to leave auto mode, and the mode you leave it for advertises going straight back.

Dropping a whole session out of auto mode to run one command is a far bigger interruption than the prompt being asked for here, and it is where the current design leaves users on both paths.

yan-hic · 21 days ago

Adding the Remote Control angle, where the hard deny costs the most: there is no terminal on the other end.

Setup (Claude Code 2.1.280, Linux): claude remote-control --permission-mode bypassPermissions, driven only from the Android app. I don't work at the host at all.

What happens

  1. On attach the app sends set_permission_mode: auto and the session accepts it one second after spawn, overriding the daemon's flag (#87826). The Android picker offers no bypass (#79990), so auto is the practical mode.
  2. In auto mode a block is final. The docs' fallback ("3 blocks in a row or 20 total, then Claude Code resumes prompting") does not apply: the child is a -p stream-json process, which the docs describe as having "no prompt to fall back to". The session tells me to "run the command yourself", and from a phone I can't.
  3. Yet the prompt channel works in that same session. Switch the app to Manual and the permission prompt reaches the phone, and I approve or deny it there. So the pieces for the requested ask disposition are already in place for Remote Control; the block just isn't routed to them.

Why the current options don't fit a phone-only user

  • Manual: works, but it asks about everything the classifier would have cleared on its own.
  • Auto: clears most actions, then hard-denies the rest with nowhere to go.
  • Bypass: not selectable from the app, and anything that approves everything gives up the classifier completely, which I don't want.

What's missing is the combination this issue proposes: auto approves what it can, and asks about what it would block. For Remote Control I'd make ask the default rather than an opt-in, because the user in a Remote Control session is by definition present on a client that can answer prompts.

mmulvanny · 8 days ago

My use case is for mostly-attended sessions where I use auto mode to avoid approval fatigue and get some other work done. I was able to work around this by adding a PermissionDenied hook that kills the Claude process - PermissionDenied hooks don't seem to respect continue: false, and the session keeps going after Claude has potentially taken a new direction based on the denial.

It's still easier than copying commands out to run by hand: I copy the claude --resume command, shift+tab to manual mode, and tell Claude to continue. Plus, the killing approach stops the harness from saving the auto-mode block, so it looks to Claude like I just interrupted the session (although I haven't actually had problems with Claude treating the auto-mode classifier as authoritative once I manually resume).