Bug: Claude directly edits settings.local.json with malformed permission patterns

Resolved 💬 3 comments Opened Feb 4, 2026 by hrp Closed Feb 8, 2026

Description

When approving a complex Bash command (e.g., gh pr edit with a heredoc body) through Claude Code's permission prompt, the system saves the entire literal command as a permission pattern instead of extracting a sensible pattern. This creates an invalid entry that fails validation and prevents Claude Code from starting.

Steps to Reproduce

  1. Have Claude run a complex command like:

``bash
gh pr edit 12345 --body "$(cat <<'EOF'
Some multiline content...
EOF
)"
``

  1. Approve the command with "Always allow"
  2. Claude Code saves the full literal command to settings.local.json
  3. On next startup, the settings file fails validation

Actual Behavior

The permission system saved an entry like this to settings.local.json:

"Bash(gh pr edit 12345 --body \"$\\(cat <<''EOF''\n### Some title\n\nSome content with special characters and newlines...\nEOF\n\\)\")"

On startup, this causes the error:

The :* pattern must be at the end. Move :* to the end for prefix matching, or use * for wildcard matching.

The settings file is then skipped entirely, losing all configured permissions.

Expected Behavior

  1. The permission system should extract a sensible pattern from complex commands (e.g., Bash(gh pr edit:*) or Bash(gh pr edit *))
  2. The system should never write an invalid pattern that fails its own validation
  3. If pattern extraction is uncertain, it should perhaps prompt the user for what pattern to save

Environment

  • Claude Code CLI
  • macOS

Impact

  • Settings file becomes invalid and is skipped on startup
  • User loses all configured permissions until manually fixed
  • User has to identify and remove the malformed entries

Suggested Fix

  1. Add validation before writing patterns to settings files - never write something that would fail validation on read
  2. Improve pattern extraction for complex commands with heredocs, subshells, quotes, etc.
  3. Consider falling back to a simple prefix pattern when the command is too complex to parse

View original on GitHub ↗

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