Permission allow-list captures entire literal commands instead of extracting command patterns
Resolved 💬 4 comments Opened Jan 30, 2026 by karptonite Closed Feb 28, 2026
Description
When approving Bash commands to add to the permission allow-list, Claude Code captures the entire literal command instead of extracting a sensible command pattern. This results in:
- Malformed/bloated settings files
- Permission rules that will never match future commands
- Multi-line commands getting split into nonsensical individual entries
Reproduction Steps
Case 1: Simple command with complex arguments
- Run a command like
gh issue create --title "..." --body "$(cat <<'EOF'...EOF)" - Approve it for the allow-list
- Check
.claude/settings.local.json
Expected: Bash(gh issue create:*) or similar pattern
Actual: The entire literal command including the full heredoc body is stored verbatim (~2KB of text in one permission rule)
Case 2: Multi-line bash constructs
- Run a for-loop or similar multi-line bash construct
- Approve it
Actual result in settings:
"Bash(for i in {1..15})",
"Bash(do)",
"Bash(if tail -5 /tmp/claude/ng-serve.log)",
"Bash(then)",
"Bash(break)",
"Bash(fi)",
"Bash(done)"
These are fragments of a for-loop, not valid standalone commands.
Environment
- Claude Code Version: 2.1.25
- OS: macOS Darwin 25.2.0
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗