[BUG] Bash(ls:*) allow rule still prompts for ls commands in settings.local.json
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?
I have Bash(ls:*) in my project's .claude/settings.local.json allow list, but Claude Code still prompts me to approve ls commands. I'm also in "Edit Automatically" permission mode, which I initially expected would help, but I understand that mode only affects file edits, not Bash commands.
What Should Happen?
The Bash(ls:*) allow rule should match any command starting with ls and auto-approve it without prompting.
Error Messages/Logs
Steps to Reproduce
Add "Bash(ls:*)" to .claude/settings.local.json → permissions.allow
Start a conversation where Claude runs a command like:
ls -la /c/Users/jonat/Documents\ \(Local\)/pinman/pinman2/envdata/source_fixtures/richtree/
Claude Code prompts for approval instead of auto-approving
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
v2.1.71
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
Looking at the docs, it appears the tool: syntax (with colon) may be deprecated in favor of tool (with space), e.g. Bash(ls *). However:
It's unclear whether the colon syntax still works at all or silently fails
There's no migration warning or documentation calling out the deprecation clearly
If the colon syntax is broken, many users with older configs will hit this silently
Additionally, the path in my command contains escaped parentheses (\(, \)) and escaped spaces — special characters in command arguments may also be interfering with the prefix matcher.
Environment:
Platform: Windows 11 (Git Bash)
Claude Code: latest (as of 2026-03-12)
My full allow list for reference:
"Bash(ls:*)",
"Bash(cat:*)",
"Bash(find:*)",
"Bash(grep:*)"
Suggestion:
If :* is deprecated, emit a warning or auto-migrate to the space syntax
Document the exact matching semantics for Bash allow rules more prominently
Clarify that "Edit Automatically" mode does not affect Bash command approval (this is a common point of confusion)
12 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Facing similar here for Next.js projects, closed my own issue https://github.com/anthropics/claude-code/issues/33827 so this can get consolidated.
Same issue. It's a real pain, and it's not just
lsbut basically all Bash commands from what I can tell.grep,tail, etc. None of my allow configuration seems to be respected anymore.Experiencing on
MacOS Tahoe 26.3.1withClaude Code 2.1.75.Almost positive it's when a bash command has unescaped
()characters in it's arguments.Quick script to reproduce with
ls:Result:
Same issue here for a next.js project with
(route-groups)in file paths 👍Same issue here. My project lives on a Google Drive path with spaces, and I have
"Bash"(bare, matches all) inallowwith specific patterns like"Bash(git push *)"in bothaskanddeny— neither takes precedence over the broad"Bash"allow.Tested on macOS Tahoe, Claude Code in VS Code, Opus model:
"Bash"inallow+"Bash(git push *)"inask→ push runs without prompting"Bash"inallow+"Bash(git push *)"indeny→ push still runs without prompting"Bash(git diff *)"inallow(no bare"Bash") →git diff --stat HEAD~1still promptsSo the pattern matching is broken in both directions: specific rules can't override a broad allow, and specific allow rules don't match multi-arg commands.
Update/workaround: We worked around this by removing bare
"Bash"fromallowentirely and using aPreToolUsehook for granular bash command permissions. The hook inspects the command string and returnsallow,ask, ordenydynamically.The hook script splits compound commands (
&&,;,|), checks each subcommand against allow/ask/deny patterns usinggrep -qEwith[[:space:]](not\s— macOSgrep -Edoesn't support it), and returns the appropriatepermissionDecision. This gives full control that the permissions system currently can't provide.Note: if your project path contains spaces (e.g. Google Drive),
$CLAUDE_PROJECT_DIRin the hook command path won't work — use a quoted absolute path instead.@sapient-christopher good job! Could you provide your
bash-permissions.shscript?@nikicat see attached.
bash-permissions.sh
@sapient-christopher thanks!
/tmp/gh-comment-body.txt
Worth pointing out that this still happens _even when the parens are in a single-quoted string_