settings.local.json accumulates invalid permission entries (heredocs, shell fragments)
Bug Description
settings.local.json (both global ~/.claude/ and project-level .claude/) accumulates invalid and malformed permission entries over time. This causes /doctor to report "Invalid Settings" errors and the file grows with junk entries that should never have been persisted.
Reproduction
- Use Claude Code normally over several sessions
- Run
/doctor - Observe "Invalid Settings" errors from malformed permission entries
What gets persisted incorrectly
1. Heredoc content saved as permission patterns
When a user approves a Bash command that contains a heredoc, the entire heredoc content (potentially hundreds of lines) gets saved as a single permission entry. Examples from my settings file:
"Bash(/tmp/test_hnsw.rs << 'ENDTEST'\nuse hnsw_rs::prelude::*;\nuse hnsw_rs::hnsw::Hnsw;\n...100+ lines of Rust code...\nENDTEST)"
"Bash(git commit -m \"$(cat <<''EOF''\nfeat(hir): wire concurrency expressions through HIR lowering\n...50+ lines of commit message...\nEOF\n)\")"
These are one-off commands that will never match again. They bloat the file and can trigger validation errors (e.g., when the heredoc content happens to contain patterns like :* that confuse the permission parser).
2. Shell fragments saved as standalone permissions
Parts of bash loops/conditionals get split out and saved as individual permission entries:
"Bash(then)",
"Bash(else)",
"Bash(fi:*)",
"Bash(done)",
"Bash(do:*)",
"Bash(while:*)",
"Bash(1)"
These are not valid standalone commands - they're fragments of multi-line shell constructs.
3. Shell conditional fragments
"Bash(then echo \"$repo\")",
"Bash(else echo \"✗ $repo (missing)\")",
"Bash(then has_sec=\"\")",
"Bash(! grep -q \"rsr-template-repo\" STATE.scm)",
"Bash(! test -d .machines_readable)"
Specific /doctor error
The entry that triggered the validation failure:
Invalid Settings
/var/mnt/eclipse/repos/.claude/settings.local.json
└ permissions
└ allow
└ "Bash(/tmp/test_hnsw.rs << 'ENDTEST'
...
ENDTEST)": The :* pattern must be at the end.
Expected Behavior
- Heredoc commands should either not be persisted as permission patterns, or should be normalized to just the command prefix (e.g.,
Bash(cat <<EOF:*)or just not saved) - Shell fragments (
then,else,fi,done) should not be saved as standalone permission entries - they should be recognized as parts of a compound command and either the full compound command should be saved or nothing - Permission entries should be validated before being written to the settings file to prevent entries that will later fail
/doctorvalidation
Frequency
This happens repeatedly — multiple times per day in heavy usage sessions. The file grows continuously with these junk entries and periodically one of them triggers an actual validation error.
Environment
- Claude Code: 2.1.39 (native)
- OS: Fedora 43 (Atomic/Silverblue)
- Platform: Linux x86_64
Workaround
Manually edit settings.local.json to remove the offending entries.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗