Backslash in permissions.allow causes JSON escape corruption and broken agent behavior
Bug Description
Putting a backslash-prefixed command in permissions.allow in .claude/settings.json causes silent corruption via JSON escape sequences, and in our case broke the agent internally (unable to generate correct tool calls, repeatedly outputting wrong commands).
Steps to Reproduce
- Add this to
.claude/settings.jsonpermissions.allow:
``json``
"Bash(\builtin cd:*)"
- Run a command like
\builtin pwd - The permission rule never matches (agent always prompts for permission)
- Worse: the agent's behavior degrades — in our case it became unable to generate the correct Bash command, repeatedly outputting
builtin pwdinstead ofbuiltin cd /tmp && pwd
Root Cause
\b is a valid JSON escape sequence (backspace character, U+0008). So "Bash(\builtin cd:*)" is silently parsed as Bash(<BS>uiltin cd:*) — which never matches any command.
This affects any backslash sequence that happens to be a valid JSON escape: \b, \n, \t, \r, \f.
Expected Behavior
Either:
- Warn or error when settings.json contains permission patterns with JSON escape sequences that are likely unintentional (e.g.,
\bin a Bash pattern) - Document that backslashes in permission patterns need to be doubled (
\\builtin) due to JSON escaping - Use raw string matching that doesn't go through JSON escape interpretation for the pattern content
Workaround
Use builtin cd instead of \builtin cd — they're functionally identical in bash, and builtin doesn't start with a backslash.
Environment
- Claude Code CLI
- Linux (WSL2)
.claude/settings.jsonwithpermissions.allowarray
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗