Permission system saves entire heredoc contents as Bash permission entry

Resolved 💬 6 comments Opened Feb 12, 2026 by ukogan Closed Apr 2, 2026

Bug Description

When a Claude Code session uses Bash with heredoc/cat << EOF syntax to write files, and the user clicks "Allow" or "Don't ask again" on the permission prompt, the entire command including all file contents is saved verbatim as a single permission entry in .claude/settings.local.json.

This corrupts the settings file with multi-kilobyte entries that are not functional permissions.

Reproduction Steps

  1. Have Claude Code write a file using Bash heredoc:

``bash
cat > /path/to/file.md << 'EOF'
# Large markdown file contents
... (thousands of characters)
EOF
``

  1. When the permission prompt appears, click "Allow" or "Don't ask again"
  2. Check .claude/settings.local.json

Expected Behavior

Either:

  • The permission should be normalized/truncated to a pattern like Bash(cat > /path/to/file.md:*)
  • Or heredoc commands should not be saved as permission entries at all (since the Write tool should be used instead)

Actual Behavior

The full command including all file contents is saved as a single permission entry:

"Bash(/path/to/file.md << 'EOF'\n# Full file contents here\n... (3000+ characters) ...\nEOF)"

This causes:

  • settings.local.json to balloon from ~2KB to 50KB+
  • Invalid/non-functional permission entries
  • The file becomes unreadable and must be manually cleaned
  • Recurring corruption if the pattern keeps happening across sessions

Environment

  • Claude Code (CLI)
  • macOS (Darwin 25.2.0)
  • Multiple concurrent Claude Code sessions on same project accelerate the issue
  • Both project-level .claude/settings.local.json and global ~/.claude/settings.local.json affected

Observed Corrupted Entries (examples)

Entries like these appeared in settings.local.json:

"Bash(/path/to/research/map-ux-study/WORKFLOW.md << 'EOF'\n# Map UX Research Workflow\n\n```\n┌────────...3000+ chars...EOF)"
"Bash(/path/to/research/map-ux-study/FINDINGS-TEMPLATE.md << 'EOF'\n# Map UX Research Findings\n...5000+ chars...EOF)"
"Bash(Skip\" for September. Reduced max crowd penalty to 30%...commit message contents...EOF\n\\)\")"

Also saw shell loop fragments saved as individual permissions:

"Bash(for dir in */)"
"Bash(do)"
"Bash(then)"
"Bash(fi)"
"Bash(done)"

Suggested Fix

When saving a Bash permission entry, either:

  1. Truncate the command at a reasonable length (e.g., 200 chars) and replace the rest with *
  2. Reject heredoc patterns entirely from being saved as permissions
  3. Normalize the permission to just the command prefix before the heredoc marker

🤖 Generated with Claude Code

View original on GitHub ↗

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