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
- 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
- Select "Always allow" when prompted
- The full heredoc gets saved as a permission entry in
.claude/settings.local.json
- 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:
-
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
-
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)
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
.claude/settings.local.jsonExpected Behavior
Two improvements:
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:
Bash(cat > /tmp/report.md *))Don't skip the entire file for one bad entry. Currently, a single malformed permission entry causes the whole
settings.local.jsonto 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
:*pattern validator rejects it because colons appear throughout the contentImpact
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