settings.local.json auto-append corrupts JSON with complex Bash commands

Resolved 💬 3 comments Opened Feb 10, 2026 by Wursthub Closed Feb 14, 2026

Bug

When a user approves a Bash command in Claude Code's permission prompt, the exact command string is auto-appended to .claude/settings.local.json. Complex commands containing heredocs, nested quotes, escaped parentheses, or multi-line strings produce entries that fail JSON parsing on the next session startup.

Reproduction

  1. Start a Claude Code session in any project
  2. Have Claude run a complex Bash command, e.g.:

```bash
gh release create v1.0.0 --title "v1.0.0" --notes "$(cat <<'EOF'
## Release notes

  • Feature (with parens)

EOF
)"
```

  1. Approve the permission prompt
  2. Close the session, start a new one
  3. Result: Settings Error on startup — the saved entry can't be parsed back

Error shown on startup

Settings Error

C:\Users\...\settings.local.json
 └ permissions
   └ allow
     └ "Bash("/c/Program Files/GitHub CLI/gh
       └ exe" release create v0
         └ 1
           └ 0 --title "v0
             ...
             
The :* pattern must be at the end.

Additional issue: redundant appends when wildcards exist

Even when .claude/settings.json (the committed, non-local file) already contains a matching wildcard pattern like Bash(git *), approving a git commit command still causes an append to settings.local.json with the exact command string. This means:

  • settings.local.json grows indefinitely across sessions
  • Wildcard patterns in settings.json don't suppress the auto-append behavior
  • Users have to periodically clean settings.local.json manually

Expected behavior

  1. Complex command strings should be safely serialized to JSON, or simplified to a wildcard pattern before saving
  2. If a wildcard in settings.json already matches the command, no entry should be appended to settings.local.json
  3. At minimum, entries that would produce invalid JSON should not be written

Workaround

Pre-populate .claude/settings.json (committed, not auto-modified) with broad wildcard patterns:

{
  "permissions": {
    "allow": [
      "Bash(git *)",
      "Bash(bash *)",
      "Bash(gh *)"
    ]
  }
}

This reduces (but doesn't fully eliminate) the auto-append behavior, since Claude Code doesn't need to prompt for commands matching these patterns.

Environment

  • Claude Code CLI (latest as of 2026-02-10)
  • Windows 11 + Git Bash
  • Also likely reproducible on macOS/Linux with any complex Bash command containing heredocs

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗