Permission auto-learning incorrectly parses multi-line bash commands

Resolved 💬 3 comments Opened Dec 26, 2025 by jhibb Closed Dec 29, 2025

Description

When approving multi-line bash commands, Claude Code's permission learning system incorrectly splits and saves them as separate permission entries, corrupting .claude/settings.local.json.

Steps to Reproduce

  1. Run a multi-line bash command (e.g., a for loop, heredoc, or command with embedded newlines)
  2. Approve the command when prompted
  3. Check .claude/settings.local.json

Expected Behavior

Multi-line commands should be saved as a single permission entry with proper escaping.

Actual Behavior

Commands are split on newlines, resulting in invalid entries like:

  • Bash(do), Bash(then), Bash(else), Bash(fi), Bash(done) (shell control fragments)
  • Bash(if [ -f "$skill/SKILL.md" ]) (partial conditionals)
  • Heredoc content saved as permissions (e.g., a git commit message body became a permission)
  • __NEW_LINE__ fragments from echo statements
  • Comment lines (starting with #) saved as separate permissions

Example of Corrupted Entries

"Bash(for skill in machine-learning-skill lightgbm-knowledge-skill...)",
"Bash(do)",
"Bash(if [ -f \"$skill/SKILL.md\" ])",
"Bash(then)",
"Bash(elif [ -d \"$skill\" ])",
"Bash(else)",
"Bash(fi)",
"Bash(done)",
"Bash(2nd Neo4j Special Edition\" book (53 pages). Downloaded fresh copy...)"

Impact

  • Settings file grows with garbage entries (observed 240 entries with ~130 invalid)
  • May cause settings parsing errors or unexpected behavior
  • Requires manual cleanup of the settings file

Environment

  • OS: Linux (WSL2) - Linux 6.6.87.2-microsoft-standard-WSL2
  • Shell: bash

View original on GitHub ↗

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