[BUG] settings.local.json allow not working - keeps asking and wanting to add existing items again
Open 💬 42 comments Opened Aug 30, 2025 by tonydehnke
💡 Likely answer: A maintainer (bogini, collaborator)
responded on this thread — see the highlighted reply below.
Environment
- Platform (select one):
- [ ] Anthropic API
- [ ] AWS Bedrock
- [ ] Google Vertex AI
- [x] Other: Claude Code on MacOS in VS Code
- Claude CLI version: 1.0.98 (Claude Code)
- Operating System: MacOS 15.6.1 (24G90)
- Terminal: Apple Terminal
Bug Description
Claude Code keeps asking permission to run commands already saved in the settings.local.json file, even suggesting to add allow again with the exact same format. Have rebooted etc, same result. Happen across multiple commands.
Steps to Reproduce
Get Claude Code to do an action, it will ask permission to do things that are in the allow section already.
Expected Behavior
Don't ask to do things that are covered in the settings allow section
Actual Behavior
Keeps asking for permission, despite it being pre-approved
Additional Context
This was reported before, but closed without resolution:
ttps://github.com/anthropics/claude-code/issues/2560
42 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Looks like a widespread issue, having the same thing on Fedora Linux 42 / vscode, after asking me for the same read permission on the same directory 4x I had this in my settings.json
Not sure in which of the many identical issues to put this, so I'm hoping someone catches it here:
I believe the issue stems from inconsistent expansion of the ~ sign (home folder).
Sometimes Claude will try to read from the relative path (~/someFolder), and when you approve the action, the actual permission written to the settings will be "Read(/home/<username>/someFolder/**)"
But when Claude tries again to read from ~/someFolder, it will not match the rule in the settings JSON.
Manually adding the relative path (as ~/someFolder) to permissions (from Claude /permissions or directly to settings json) will resolve the issue.
I believe a proper solution would be for claude to identify home-folder paths, and add both the relative and absolute paths to the 'allowed' list, so both versions will work (or for Claude to always expand homefolder paths behind the scenes?)
Hey @tonydehnke! I think you're encountering this because of wrong path format in your permissions. See https://docs.anthropic.com/en/docs/claude-code/iam#tool-specific-permission-rules.
The fix: Use
//for absolute paths on macOS:Quick cheat sheet:
//path→ absolute path (use for/Users/...)~/path→ from home directory/path→ relative to settings file (this is what's tripping you up)Update your
settings.local.jsonwith the double slashes and the repeated prompts should stop immediately.Thanks @bogini, but
claudeitself is adding these incorrect lines (see more examples in #7015).Update: I'm also not seeing the manual fix (two leading slashes) have any effect, I'm still getting prompted for reads that should be covered by them.
I don't know if anyone met this, auto accept edit also not working with Claude Code version 1.0.103 this morning
I have a same problem too.
I have randomly started experiencing this today too. If you are running CC on windows, you can try referencing your path for the permission this way:
"Read(RelativePath/to/someFolder/)",
"Edit(RelativePath/to/someFolder/)",
However, I think this underlines a bigger issue with the CC startup. It seems to somehow lose the linkage when restarted even within the same home directory of the codebase. Not sure why.
Edit: Obviously downgrading will fix the issue, but my answer is for people who want to have access to the latest CC version and new features.
worked for me thks very much!
And anyone can try this:
Read(**)
Yes this worked!
I put this in my workspaces .claude folder
.claude/settings.local.json
Non of the recommended workaround work for me on Windows. I tried
Have you updated your Claude Code yet? the issue was already resolved in newest version.
I'm on the latest version and still have these problems. #7207
For what it is worth, I was not able to get the simpler permissions matching to work with the prefix matching either, i.e., the issue discussed here. However, I was able to use a hook to filter my 'grunt test:*' content.
If that helps, here is the configuration I used:
settings.json
Added the following:
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/grunt_test_hook.sh",
"timeout": 30
}
]
}
]
}
and my script:
#!/usr/bin/env bash
set -euo pipefail
Read JSON from stdin
input="$(cat)"
tool_name="$(jq -r '.tool_name // ""' <<<"$input")"
cmd="$(jq -r '.tool_input.command // ""' <<<"$input")"
Only handle Bash tool
if [[ "$tool_name" == "Bash" && "$cmd" == grunt\ test* ]]; then
cat <<'JSON'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "Auto-allowing grunt test*"
}
}
JSON
else
# Do nothing; normal permission system applies
echo "{}"
fi
The relevant documentation: https://docs.claude.com/en/docs/claude-code/hooks and https://docs.claude.com/en/docs/claude-code/hooks-guide.
I'm experiencing what appears to be a related issue with permissions being overridden. I have explicit "ask" permissions configured in my .claude/settings.local.json for git operations:
"ask": [
"Bash(git add*)",
"Bash(git commit*)",
"Bash(git push*)"
]
However, Claude is executing git add and git commit commands without requesting approval. When I asked Claude what permissions it sees in its system instructions, it reported having Bash(git add:) (with a colon) in the allow list, despite this not being present in my settings file. This suggests either: 1) a pattern-matching issue where git add in my "ask" list doesn't match git add:* that the system is checking against, or 2) permissions are being cached/inherited from a previous session. This occurred in a "continued conversation" (a session resumed after a previous conversation ran out of context). It's possible that continued conversations are inheriting old permissions from prior sessions rather than reloading the current settings file. This is a critical issue since it allows Claude to modify git repository state without user consent, completely bypassing explicitly configured permission guards. The expected behavior is that any "ask" permission should always require user approval, regardless of pattern variations or session continuation.
@keithdan it may be a typo in your message, but it reads "Bash(git add)",and it should be "Bash(git add:)", with the semicolon. I noticed that typos in the config file make the whole config be silently ignored.
any update on this issue?
calude 2.0.27 STILL ignores settings.local.json allow permissions. it keeps asking and (sometimes) adding the commands to the list (when I hit "2") but completely ignores them
@ytzhakov Not sure if this helps, but it took me a while to realize that errors in settings files do not cause errors on claude start up, but if you invoke the /status command, you will see if there is an error in the file. For example, you'll see something like:
System Diagnostics
⚠ Found invalid settings files: <your-code-repo-directory>/.claude/settings.json. They will be ignored.
This can give the sense that settings are ignored, where in fact, it may be due to a typo. I have found these hard to debug because the error message is not specific about the error, but I was able to fix the issue.
@vhardy this is what status shows at the bottom:
System Diagnostics
⚠ Found invalid settings files: . They will be ignored.
im not sure what it means because there is no file name. Additionaly, calude itself adds the "allow" permissions to settings.local.json when I hit "2" (always allow....).
I've tried removing all permissions and let calude add them on its own again - same issue.
it just wouldnt honor these settings. I tried using wildcards as well, for example:
"Bash(MSYS_NO_PATHCONV=1 \"C:/Program Files/Microsoft Visual Studio/2022/Enterprise/MSBuild/Current/Bin/MSBuild.exe\":*)",
"Bash(MSYS_NO_PATHCONV=1 \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Current\\Bin\\MSBuild.exe\":*)",
nothing seems to work. it just keeps asking me every time it wants to build the project
Detailed Investigation Report: Permissions Ignored Despite Explicit Configuration
### Environment
.claude/settings.local.json### Problem Statement
Claude Code repeatedly requests permissions for actions explicitly allowed in
.claude/settings.local.json, including:uv run ruff check,uv run ruff format,uv run python -m py_compilemcp__basic-memory__edit_note,mcp__basic-memory__write_note, etc.All of these permissions were explicitly listed in the
permissions.allowarray.### Investigation Steps
#### Theory 1: Path Format Issue (Single vs Double Slash)
Based on issue #6850 and #6881, we hypothesized that absolute paths needed double slashes (
//) on macOS.Changes Made:
```
// Before
"Read(/Users/arnon/projects/**)"
"Bash(/Users/arnon/bin/send_text:*)"
// After
"Read(//Users/arnon/projects/**)"
"Bash(//Users/arnon/bin/send_text:*)"
Result: ❌ Failed - Still requested permissions
Test Method: Fresh Claude instance, asked to run uv run ruff check on a file
Outcome: Permission prompt appeared despite pattern being in allow list
Theory 2: Wildcard Syntax Issue (Colon vs Space)
Based on issue #819, we hypothesized that command:* syntax doesn't match space-separated arguments.
Changes Made:
// Before
"Bash(uv run ruff check:*)"
"Bash(uv run ruff format:*)"
// After
"Bash(uv run ruff *)"
Result: ❌ Failed - Still requested permissions
Test Method: New Claude instance after configuration change
Outcome: Still prompted for permission to run uv run ruff check bin/checked_bash.py
Theory 3: Configuration File Corruption
Rolled back .claude/settings.local.json to a known-good version from Oct 27 (commit a079a14) using git.
Result: ❌ Failed - Still requested permissions with old configuration
Test Method: Fresh Claude instance with rolled-back configuration
Outcome: Permissions still requested, ruling out configuration file as the cause
Evidence of Core Bug
Verification Steps Taken
# Verified settings file exists and contains permissions
$ grep -n "edit_note" .claude/settings.local.json
39: "mcp__basic-memory__edit_note",
# Verified only one settings file in project
$ ls -la .claude/settings*.json
-rw-r--r--@ 1 arnon staff 2845 Nov 6 12:09 .claude/settings.local.json
# Tested with git history
$ git log --oneline -- .claude/settings.local.json
ffe4d62 FLO-72: Add customers table page with sortable columns
99fa209 FLO-72: Implement users table page infrastructure
a079a14 FLO-72: prep for implementing table pages
# Rolled back and tested
$ git checkout a079a14 -- .claude/settings.local.json
# Result: Still prompted for permissions
Screenshot Evidence
Permission prompt appeared for uv run ruff check bin/checked_bash.py despite:
Conclusion
The permission system in Claude Code 2.0.34 does not read or respect .claude/settings.local.json at all, or the pattern matching is completely broken for all pattern types.
This is not caused by:
This appears to be a fundamental bug in the permission system initialization or matching logic affecting:
The system prompts for permissions on every fresh instance regardless of configuration, making the settings file effectively non-functional.
Reproducibility
100% reproducible on every fresh Claude Code instance with any configuration pattern tested.
```
This critical security bug has been open for 3 months with no progress. Permission system is completely non-functional in v2.0.34. Escalating to
security@anthropic.com and support@anthropic.com
I just encountered this -- I had an old-style hook in
settings.json, which was deprecated (without any warning 😧 ) in 2.0.32. This caused the entire settings.json to be ignored-- I guess not technically "silently" since there is a brief message on startup. But that's a pretty dangerous failure mechanism, since it means that upon an upgrade, suddenly project-wide guardrails will be dropped.Now with
v2.0.50, the issue is still there, cannot believe that, the issue was there since day one of v2, it just cannot be fixed?Still an issue. I feel like this should be THE top priority issue. The permission system basically does not work for me. I can't leave it unattended for more than 15 seconds...
One thing I'm finding is if there is an error in setting.local.json, claude keeps trying and asking permission. It would be much better if it said "There is an error in the permissions file, would you like me to fix it, fix it yourself, or fix later".
Also running into this on Linux
Three months and still the same problem? That's weird!
Workaround: use PermissionRequest hook
I had problems with the Read operation on some files.
Since Read permissions in settings.json are ignored despite correct configuration, I used a PermissionRequest hook to auto-approve Read operations.
For VS Code
```
"hooks": {
"PreToolUse": [
{
"matcher": "Read",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/allow-read.sh"
}
]
}
]
}
#!/bin/bash
echo '{"hookSpecificOutput": {"hookEventName": "PermissionRequest", "decision": {"behavior": "allow"}}}'
exit 0
"hooks": {
"PermissionRequest": [
{
"matcher": "Read",
"hooks": [
{"type": "command", "command": "~/.claude/hooks/allow-read.sh"}
]
}
]
}
This is driving me crazy. I'm having issues w/ it on linux and macos.
The disconnect between documented behavior and actual behavior suggests the permission system wasn't tested against the documented spec. A TDD approach where tests validate the documented patterns would catch these gaps.
Specific issues encountered:
This inconsistency makes it nearly impossible to configure Claude Code reliably without --dangerously-skip-permissions.
It's 2026 and we're still having issue.
If this is the quality of the AI product that writes code for me, I don't know how you expect us to trust the code it's writing. (not that I trust it at all in the first place)
Confirming Solution from #6881
After extensive debugging, I can confirm @bogini's solution works:
The Fix
Use double-slash
//for absolute paths insettings.jsonorsettings.local.json:Why Single-Slash Fails
| Format | Interpretation |
|--------|----------------|
|
/Users/james/**| Relative to settings file (WRONG) ||
//Users/james/**| Absolute filesystem path (CORRECT) ||
~/projects/**| Home directory expansion (CORRECT) |Additional Finding
Path-restricted Bash commands also fail:
Bash(rm:/tmp/**)doesn't matchrm /tmp/file.txt. Use wildcards instead:Bash(rm:*)with appropriate deny rules.Recommendation
Claude Code should either:
//format when users accept permission prompts, ORCurrently Claude generates single-slash paths which perpetuates the problem.
This is still not working, especially with Tasks. Asking Claude to fix the permissions issue, or even simply add * under alwaysApproveToolUsePatterns permissions and normal permissions, does not help.
Got tired of waiting for fixes. Created https://github.com/arnonmoscona/toolguard as an enhanced drop-in replacement to the native permissions system using hooks. As far as I can tell it is syntax-compatible, but it has more features and allows also new matching patterns. The simplest setup is just to setup the hook as documented, but you can go far beyond if you want. I will add a new feature soon to overcome some of the annoying behaviors I find around permissions.
I'd welcome any feedback, comments, PRs. This is new, to treat it carefully. "works on my machine" is not really good enough, but I am one guy with one machine. So there's that...
Why is this bug still open and having duplicates filed? There are two issues:
1 cannot be fixed as the input requires natural language processing and there is no way to ensure users don't want the edits made since it is valid syntax
2 can only be fixed by a specification change - for example, switching from "Read(customgitignoreglob)" syntax to "Read[gitignoreglob]" or Read.unix(unixglob) etc.
1 will receive new duplicate bugs and should be closed with WONTFIX and a friendly reminder to read the opening claude disclaimer "Claude can make mistakes" before using the tool or expect consequences.
2 may depend on an analysis of how many bug reports/upvotes this problem receives
Additional reproduction: Linux CLI, Glob + Read affected, symlink paths
Environment: Claude Code CLI v2.1.50, Debian Linux, working directory
/opt/projects/Allow rules on both global and project level:
Affected tools:
Glob(pattern: "INDEX.md", path: "/export/data/docs")→ prompts for permission ❌Read("/home/jens/.claude/CLAUDE.md")→ prompts for permission ❌Bash(git -C /export/data/docs status)→ works fine ✅Notes:
/opt/projects/docsis a symlink →/export/data/docs, rules exist for both pathsReadon/home/jens/.claude/CLAUDE.mdalso prompts despite matching rules (no symlink involved)This is very annoying and still present even in 2.1.71
How is this still an issue? Vibe coded slop
The allow list in
settings.local.jsonhas known pattern-matching limitations (see #30519 for the full catalogue). The most reliable workaround is a PreToolUse hook that implements your own allow logic:This bypasses all the pattern-matching bugs:
&&,|,;)Add or remove commands from the
casestatement to match your needs.Possible 2.1.87 regression: tool permission "Always allow" accepted but never written to disk
Adding a data point that may help narrow this down — specifically around
settings.local.jsonnot being written at all, rather than pattern-matching issues.Environment
~/.claude(via alias — creates project-scoped config at~/.claude/.claude/settings.local.json, which is expected behavior)additionalDirectoriesprompt covered in #7472Observation
settings.local.jsonhas not been modified since before the 2.1.87 upgrade, despite multiple "Always allow" clicks across sessions:lsofshows the file is only ever opened read-only — never for writing:Both running 2.1.87 processes hold
r(read-only) file descriptors onsettings.local.json. Norworwfd is observed at any point — including immediately after clicking "Always allow." The rule is accepted in-memory for the session but the write to disk never happens.What was ruled out
settings.jsonask/deny rules don't matchsettings.local.jsonpath — no config blocking the writefs.writeFileSynccalls made by Claude Code itselfPrior version behavior
The file was being written normally under 2.1.86. The last entry in
settings.local.jsondates to Mar 28 08:00, under 2.1.86 (installed Mar 27 18:04). Nothing has been written since the 2.1.87 upgrade later that day.This suggests the issue may not be pattern-matching (the existing focus of this thread) but rather the write to
settings.local.jsonnever being triggered at all in 2.1.87. Happy to provide any additional diagnostic info.Thanks for the report. This is a duplicate of #6881 — consolidating tracking there.
[FYI toolguard is now at 0.3.0 - while takeover mode is nominally in alpha state, it's been working perfectly for me for a while. So this issue does not really affect me any more and I have a much more flexible permissions configuration.
https://github.com/arnonmoscona/toolguard](https://github.com/arnonmoscona/toolguard)