[BUG] /permissions silently drops existing rules with lowercase tool names when adding a new rule
Preflight Checklist
- [ ] 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?
When .claude/settings.json already contains permission rules using a lowercase tool name (e.g. bash(...) instead of Bash(...)), running /permissions to add a new, correctly-cased rule causes the existing lowercase rules to be silently discarded instead of preserved or flagged as invalid.
Steps to Reproduce
Manually create .claude/settings.json with:
json
{
"permissions": {
"allow": [],
"ask": ["bash(git push *)"],
"deny": ["bash(rm -rf *)"]
}
}
Start Claude Code in that project.
Run /permissions and add a new rule, e.g. allow Bash(git commit *) under "ask".
Inspect .claude/settings.json after the change.
What Should Happen?
The existing ask/deny rules are preserved as-is even though their casing is non-standard, or
Claude Code warns the user that bash(...) is invalid (case-sensitive, should be Bash(...)) and asks whether to fix or remove it.
Error Messages/Logs
Actual Behavior
The existing rules disappear without warning:
json
{
"permissions": {
"allow": [],
"deny": [],
"ask": [
"Bash(git commit *)"
]
}
}
Steps to Reproduce
Both the ask: bash(git push ) and deny: bash(rm -rf ) rules are gone. Only the newly added, correctly-cased rule remains.
Impact
This is a silent data-loss / security issue: a user could have a deny rule intended to block a dangerous command (e.g. rm -rf *), and adding an unrelated permission via /permissions will quietly remove that protection with no error, confirmation, or log message.
Environment
Claude Code version: (fill in claude --version)
OS: (fill in)
Settings file: .claude/settings.json (project-level, shared)
Suggested Fix
Validate tool-name casing when parsing rules, and either normalize (bash → Bash) or warn rather than dropping silently.
When /permissions rewrites the settings file, preserve any rule it doesn't recognize rather than omitting it, so unrecognized-but-present configuration isn't lost.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.261 (Claude Code)
Platform
Other
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_