Claude Code 2.1.119 corrupts `.claude.json` by writing GrowthBook cache strings with raw (unescaped) newlines
Summary
Claude Code 2.1.119 intermittently writes ~/.claude/.claude.json with raw newline bytes (0x0A) inside JSON string values, producing invalid JSON. On next launch, Claude Code self-detects the corruption, moves the file to backups/.claude.json.corrupted.<ts>, and presents a "Configuration Error — Unterminated string" dialog whose only options are "Exit and fix manually" or "Reset with default configuration" (the latter wipes all user state).
Specifically, the cachedGrowthBookFeatures.tengu_flint_harbor_prompt.prompt and .guideTemplate fields are written with literal newlines rather than \n escapes.
Environment
- Claude Code: 2.1.119 (latest at time of report; released 2026-04-23)
- Platform: Linux (Debian-based Docker container)
- Installed via:
curl -fsSL https://claude.ai/install.sh | bash - Node.js: 22.22.0
CLAUDE_CONFIG_DIR=/home/node/.claude
Byte-level evidence (same process, same file, 7 seconds apart)
Claude Code itself rotates a backup right before writing. The backup is valid; the subsequent write is corrupt.
Valid backup written by Claude Code (backup.1777041841987):
"guideTemplate": "# Welcome to [Team Name]\n\n## How We Use Claude\n\nBased on..."
^^ ^^ proper JSON escapes (backslash + n)
Corrupted write by Claude Code 7 seconds later (corrupted.1777041849186):
"guideTemplate": "# Welcome to [Team Name]<0x0A><0x0A>## How We Use Claude<0x0A>..."
raw newline bytes, invalid JSON
Same file, same Claude Code process, same session. Claude Code read the value with proper \n escapes (from its own just-written backup) and wrote it back with literal newlines.
Fields affected
.cachedGrowthBookFeatures.tengu_flint_harbor_prompt.prompt(~4.5 KB, 60 raw newlines).cachedGrowthBookFeatures.tengu_flint_harbor_prompt.guideTemplate(~1.7 KB, 62 raw newlines)
No other fields are affected — the write path only mishandles these two multi-line strings.
Reproducibility
- Intermittent in real sessions: corrupts roughly every other launch on one user's machine. Correlates with the GrowthBook fetch cache cycle.
- Does NOT reproduce from a clean
.claude.json: launchingclaude -p "ok"withCLAUDE_CONFIG_DIRpointed at an empty config dir produces a valid file, even when the feature flag IS fetched and cached. So there's an accumulated-state precondition. - Host vs container: On the same machine, macOS host
claude2.1.119 caches the same feature without corruption. Only the Linux container hits it. Clean-state repros inside the container also don't hit it. The specific precondition has not been isolated.
Suggested fix
The cache-write path for GrowthBook feature values appears to decode the escaped string (into a JS string with real newlines) and then write it back without re-escaping. Should use JSON.stringify end-to-end.
Impact
- "Reset with default configuration" wipes user state. Users unfamiliar with hand-editing JSON have effectively only this option.
- Wiped state can include MCP OAuth tokens, IDE connections, session history, tips progress, etc.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗