Skip to content

Permission allow-list captures entire literal commands instead of extracting command patterns #21845

@karptonite

Description

@karptonite

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:

  1. Malformed/bloated settings files
  2. Permission rules that will never match future commands
  3. Multi-line commands getting split into nonsensical individual entries

Reproduction Steps

Case 1: Simple command with complex arguments

  1. Run a command like gh issue create --title "..." --body "$(cat <<'EOF'...EOF)"
  2. Approve it for the allow-list
  3. 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

  1. Run a for-loop or similar multi-line bash construct
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    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