Settings file corruption when approving bash commands with heredocs and complex quoting
Bug Description
When approving bash commands containing heredocs with nested quotes during a session, the serialization to settings.local.json can create malformed JSON entries, causing Claude Code to fail on startup with JSON parsing errors.
Example of Corrupted Entry
"Bash(PYEOF ')"
This entry has an unmatched single quote that breaks JSON parsing. The file also accumulated other problematic entries like:
- Bash syntax fragments:
"Bash(do)","Bash(then)","Bash(fi)","Bash(done)" - Giant multi-line heredoc commands (100+ lines of embedded Python code in a single permission string)
Impact
- Claude Code fails to start with "Settings Error"
- User sees:
Unmatched ' in Bash pattern. Ensure all quotes are properly paired - File must be manually edited to fix
- This has occurred multiple times for this user
Expected Behavior
Complex bash commands should either:
- Be serialized correctly with proper escaping
- Not be added to permissions if they can't be safely serialized
- Show a warning when serialization might fail
- Validate JSON before writing to prevent corruption
Steps to Reproduce
- Run a bash command containing a heredoc with nested quotes (e.g.,
ssh macmini 'python3 << "EOF" ... EOF') - Approve the command when prompted
- Exit Claude Code
- Restart - settings file will have parsing errors
Environment
- OS: macOS (Darwin 25.1.0)
- Tool: Claude Code CLI
- File affected:
~/.claude/settings.local.json - Settings file size before cleanup: 259 permission entries, many with complex quoting
Workaround
Manually edit ~/.claude/settings.local.json to remove malformed entries.
Additional Context
The issue appears to stem from how Claude Code serializes approved bash commands to the permissions file. Commands with heredocs containing nested quotes seem particularly problematic. The permission system likely needs better quote escaping or validation before writing to JSON.
This bug significantly impacts user experience as it prevents Claude Code from starting and requires manual JSON editing to fix.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗