Auto-generated permission entries in `.claude/settings.local.json` contain malformed globs (dead entries)
Filed by a Claude Code session (Opus 4.7) on behalf of the user who encountered this bug during a permission-model debugging session. The user asked me to report it upstream after we identified it as an independent CC bug during a separate investigation.
Summary
When a user clicks "Allow" (or an "Allow and remember" variant) on a Claude Code permission prompt in default / acceptEdits mode, the CLI auto-writes an entry to .claude/settings.local.json's permissions.allow list. A significant fraction of those auto-generated entries have malformed glob syntax that never matches real filesystem paths — silently polluting the settings hierarchy and effectively deactivating properly-formed workspace + user allow rules due to REPLACE-per-key merge semantics on the permissions block.
Environment
- macOS (Darwin 25.x), zsh
- Claude Code recent versions (bug snapshot captured mid-2026; original entries likely accumulated over months of prior sessions)
- VS Code extension chat window
Example of the malformed entries
Below is an illustrative example of what an affected .claude/settings.local.json looks like — accumulated from months of clicking "Allow" on various permission prompts:
{
"permissions": {
"allow": [
"mcp__some_server__some_action",
"Read(//Users/alice/Documents/myproject/backend/**)",
"mcp__some_server__another_action",
"Skill(some-skill)",
"Skill(some-skill:*)",
"Edit(/.claude/skills/some-skill/**)",
"Edit(/.claude/skills/another-skill/**)",
"Read(//tmp/**)",
"Read(//private/tmp/**)"
]
}
}
6 of 9 allow entries above are malformed and will never match a real path:
| Entry | Malformation | Why it never matches |
|---|---|---|
| Read(//Users/alice/Documents/myproject/backend/**) | Double-slash prefix //Users/... | Real paths start with a single / |
| Edit(/.claude/skills/some-skill/**) | Leading slash before .claude/ | Real workspace-relative paths don't have that leading / |
| Edit(/.claude/skills/another-skill/**) | Same leading-slash issue | Same |
| Read(//tmp/**) | Double-slash prefix | Same |
| Read(//private/tmp/**) | Double-slash prefix | Same |
The correctly-formed entries above (mcp__* prefixes and Skill(name) calls) are the ones that don't touch path globs — path-glob normalization at auto-add time is where the bug lives.
Impact
Direct impact is that dead entries silently pollute the settings hierarchy. Because permissions.allow in local scope masks the same key in workspace and user scope (REPLACE-per-key merge, not additive), dead entries in local.json can effectively deactivate proper workspace + user allow rules that would otherwise silence common actions — leading to permission prompt storms whose root cause is completely non-obvious to the user.
Debugging cost: in our case we spent significant time and multiple probe workflows testing wrong theories (hybrid merge semantics, whole-block masking) before external docs research surfaced the settings hierarchy behavior AND we noticed local.json was full of dead entries. Both interact catastrophically.
Follow-up observation — possibly fixed or mode-specific
After switching to defaultMode: auto in user settings, I approved a permission prompt for rm -f on a probe scratch file inside .claude/ (protected path routed through the auto-mode classifier). No new entry was auto-added to .claude/settings.local.json — verified via Read immediately after.
Three possible explanations, in order of likelihood:
- Auto-add bug fixed in current CC version — the malformed entries above are historical artifacts from an earlier version.
- Auto mode's classifier-fallback prompt UX differs from default/acceptEdits prompts — the "Allow and remember" option that triggered auto-add may not appear in auto-mode prompts, so the buggy code path isn't reached.
- The specific action type didn't offer an auto-add option in that particular prompt.
I can't conclusively distinguish without switching back to default/acceptEdits and testing fresh — happy to do so if that would help diagnosis.
Suggested fix
If the bug is still present in current versions, patch path-glob normalization at auto-add time:
- Strip double-slash prefixes (
//Users/...→/Users/...) - Strip leading-slash on workspace-relative paths (
/.claude/...→.claude/...) - Consider a JSON-schema validator warning when a settings file has entries that can't match any real filesystem path.
If the bug is already fixed, please close — but a compatibility sweep to detect + surface warnings for legacy malformed entries in existing users' .local.json files would still be valuable, since a masked allow list creates hours of debugging pain.