[BUG] permissions.ask rules never trigger when defaultMode is "auto" — matching commands auto-approved, including destructive ones
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
With defaultMode: "auto", commands matching permissions.ask patterns are auto-approved with zero ask prompts — including destructive ones.
In an 8-case controlled matrix (temp sandbox repos, each command a separate tool call), all 4 commands matching ask patterns were auto-approved with no prompt, and destructive effects executed:
git push origin HEAD(to a local bare remote) — ask list hasBash(git push:*)powershell -c "Remove-Item -Recurse <tmp dir>"— ask list hasBash(powershell:*)(directory actually deleted)powershell -c "Get-Date"— same patterngit reset --hard HEAD~1— ask list hasBash(git reset --hard:*)(commit actually rolled back)
Reproduced independently on macOS 2.1.221 and Windows 11 2.1.211. deny rules DO work (a git commit --no-verify call was blocked at the tool layer on the same config).
Config (~/.claude/settings.json):
{ "permissions": {
"defaultMode": "auto",
"ask": ["Bash(git push:)", "Bash(git reset --hard:)", "Bash(powershell:*)", "..."],
"deny": ["Bash(git commit --no-verify:*)"] } }
Confound check: our project-level settings.local.json contained broad accumulated allow rules (e.g. Bash(git:*)) covering most matrix commands, so we ran a clean control: sudo -n true — Bash(sudo:*) IS in the ask list and is covered by NO allow rule — and it still executed with no ask prompt. So the non-firing of ask is not explained by allow-rule shadowing.
What Should Happen?
Commands matching permissions.ask patterns should surface an approval prompt regardless of defaultMode — ask acting as a deterministic backstop over the auto classifier. Users configure ask precisely so that dangerous commands cannot be silently auto-approved.
Error Messages/Logs
No error output — the failure mode is silent: matching commands are approved and executed as if no ask rule existed.
Steps to Reproduce
- In
~/.claude/settings.jsonset:
{ "permissions": { "defaultMode": "auto", "ask": ["Bash(git reset --hard:*)"] } }
- Start a new Claude Code session in any git repo (or a temp repo:
git init, one commit). - Ask Claude to run
git reset --hard HEAD. - Observed: command executes immediately, no approval prompt. Expected: ask prompt.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.221 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Related observation (likely a separate issue, mention here for context): the auto classifier sometimes hard-denies benign commands matching no deny rule (pipx install ..., powershell.exe -File sync.ps1) without offering an ask prompt — while the same script invoked indirectly via a wrapper .ps1 passes. Behavior appears content/shape-based and is not stable across days. Happy to file separately if useful.
Also reproduced on Windows 11, Claude Code 2.1.211 (Git Bash).
Net effect of the two behaviors: dangerous ops that should ask are silently approved, while some benign ops are hard-blocked with no approval path. Workaround we applied: moved lethal patterns to deny (works correctly), treating the ask list as documentation only.
Related issues checked: #80242 is the opposite symptom (prompts persisting in auto mode despite allow rules). #80031 (broad allow overriding ask) was retracted by its author after a clean re-test, and was observed under default mode, not auto — our clean sudo control above also rules out allow-shadowing as the cause here.
If defaultMode: "auto" is intended to bypass the ask list entirely (classifier-only), then this is a documentation gap rather than a precedence bug — the docs' deny → ask → allow order should state that ask is not honored in auto mode, since users configure ask precisely as a safety backstop.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗