Skip to content

"Always allow" on multiline bash commands creates unparseable permission patterns #25909

@jensechterling

Description

@jensechterling

Description

When a user selects "Always allow" on a multiline bash command (e.g., a heredoc), Claude Code saves the entire multi-line command string as a permission pattern in .claude/settings.local.json. This creates entries that fail the pattern validation rule (The :* pattern must be at the end), causing the entire settings file to be skipped.

Steps to Reproduce

  1. During a session, Claude Code requests permission to run a multiline bash command, e.g.:
    cat > /tmp/report.md << 'EOF'
    # Some Report
    Content here...
    EOF
  2. Select "Always allow" when prompted
  3. The full heredoc gets saved as a permission entry in .claude/settings.local.json
  4. On next session start or settings reload, the file fails to parse with:
    Settings Error
    .claude/settings.local.json
      └ permissions
        └ allow
          └ "Bash(/tmp/report.md << 'EOF' ..."
            └ error-pages
              └ ...
                └ The :* pattern must be at the end. Move :* to the end for prefix matching...
    
    Files with errors are skipped entirely, not just the invalid settings.
    

Expected Behavior

Two improvements:

  1. Don't save multiline commands as permission patterns. When a user clicks "Always allow" on a heredoc or other multiline command, Claude Code should either:

    • Extract just the command prefix to form a valid pattern (e.g., Bash(cat > /tmp/report.md *))
    • Decline to create an "always allow" rule and inform the user that multiline commands can't be saved as patterns
    • Save only the first line/command as the pattern
  2. Don't skip the entire file for one bad entry. Currently, a single malformed permission entry causes the whole settings.local.json to be ignored. It would be more resilient to skip only the invalid entries and warn about them, while still loading the valid ones.

Actual Behavior

  • The full multiline command (sometimes 50+ lines of markdown content) is saved as a single permission entry
  • The :* pattern validator rejects it because colons appear throughout the content
  • The entire settings file is skipped, losing all other valid permission entries

Impact

In our case, the file accumulated ~50 broken entries over multiple sessions before the error surfaced, growing to 170 lines of mostly garbage. The fix required manually editing the file to remove all malformed entries.

Environment

  • Claude Code CLI
  • macOS (Darwin 25.2.0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingduplicateThis issue or pull request already existsplatform:macosIssue specifically occurs on macOS

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions