[BUG] Permission allowlist patterns cannot match Windows paths with backslashes
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?
Bug summary written by claude after trying for half an hour to get this to work without allowing global access. If its analysis is not correct, it would still be great to train it to be able to exist better in a powershell window. I'm switching to git bash due to running into several issues like this.
Bug: Permission allowlist patterns cannot match Windows paths with backslashes
Summary
On Windows, it appears to be impossible to write a specific-path permission allowlist entry for PowerShell tool calls that include Windows-style paths (backslashes). The glob engine used by Claude Code's permission system treats \ as an escape character, which means any pattern containing a Windows path will never match the actual command string.
(Or at least, claude couldn't figure out how to write a permissions entry to address this issue)
What is happening is that I'm getting permission prompts due to changes in directory when claude attempts to run git commands. I was unable to write a permission entry to avoid these for specific directories. See Repro Steps for more info.
What Should Happen?
It should be possible to write a permission pattern that matches a specific Windows path prefix, e.g. allow git read commands only when the -C path is under C:\git\repo\ or C:\git\repo2\.
When running the git command after writing the permissions entry, claude should not prompt the user for permissions.
Error Messages/Logs
Steps to Reproduce
Steps to reproduce
- Run a git command via the
PowerShelltool that includes a-C <path>argument with a Windows path:
````
git -C C:\git\repo\subrepo log --oneline -1
- Observe the permission prompt. The command string shown is:
````
git -C C:\git\repo\subrepo log --oneline -1
(backslashes, no surrounding quotes on the path)
- Try to write a permission pattern in
settings.jsonto allowlist this command for the specific pathC:\git\repo\:
``json``
"allow": [
"PowerShell(git -C C:\\git\\repo\\* log*)"
]
- The prompt still appears — the pattern never matches.
Root cause (written by claude)
The glob engine treats \ as an escape character. So the pattern string git -C C:\git\repo\* is parsed as:
\g→g\r→r\*→ literal*(escaped glob special char, not a wildcard)
The pattern effectively tries to match C:gitrepo* (literal asterisk), which never appears in the command. No amount of JSON backslash escaping resolves this — the problem is at the glob-matching layer, not JSON parsing.
All patterns tried — all failed
| Pattern in settings.json | Parsed pattern string | Why it fails |
|---|---|---|
| "PowerShell(git -C \"C:\\git\\repo\\*\" log*)" | git -C "C:\git\repo\*" log* | Quotes in pattern don't match (quotes are stripped from the command before matching) |
| "PowerShell(git -C C:\\git\\repo\\* log*)" | git -C C:\git\repo\* log* | \ treated as escape; \* becomes literal *, not a wildcard |
| "PowerShell(git -C C:\\\\git\\\\repo\\\\* log*)" | git -C C:\\git\\repo\\* log* | Two backslashes in pattern still don't match one backslash in the command |
What does work (but is too broad)
PowerShell(git -C *repo* log*) — matches, but also matches any path containing the string repo, e.g. C:\BadRepo\. There is no way to anchor to a specific directory.
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.170
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Impact
Any Windows user who wants to allowlist shell commands scoped to a specific directory is blocked. The permission system effectively forces a choice between:
- Overly broad patterns (match any path containing a keyword, always allow all git commands from any directory)
- No allowlist at all (prompt on every command)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗