[BUG] Write tool creating new .md file permanently crashes session renderer (SyntaxHighlightedDiff infinite setState loop)

Resolved 💬 3 comments Opened Feb 19, 2026 by DavidDavids Closed Feb 23, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Platform

  • OS: Windows 11 (10.0.26200)
  • Claude Desktop: v1.1.3541
  • Severity: Data loss / session permanently inaccessible
  • Reproducibility: 100% — every attempt to open the affected session crashes the app within ~1 second

---

Root Cause (Traced from Logs + Session Data)

The session JSONL contains two crash triggers for each new-file Write call.

Trigger A — toolUseResult on the user message following the Write:

{
  "type": "create",
  "filePath": "/path/to/file.md",
  "content": "<full file contents>",
  "structuredPatch": [],
  "originalFile": null
}
{
  "type": "tool_use",
  "name": "Write",
  "input": {
    "file_path": "/path/to/file.md",
    "content": "<full file contents>"
  }
}
Crash cascade (from unknown-window.log):

The renderer's SyntaxHighlightedDiff component is invoked for both the Write input display and the Write output display. It attempts to load the markdown syntax highlighting grammar (derived from the .md file path), which fails:

[USER_CONTENT_RENDERER] Failed to load language: markdown - falling back to plain text
[USER_CONTENT_RENDERER] [SyntaxHighlightedDiff] Token without row: [object Object]
Error: Minified React error #185  ← Maximum update depth exceeded (infinite setState)
[BOOTSTRAP] Fatal error boundary triggered [object Object]
Uncaught Error: Minified React error #418  ← Hydration mismatch on remount
MaxListenersExceededWarning: 11 listeners for AutoUpdater_$_updaterState

The plain-text fallback tokenizer returns token objects that lack the .row property that SyntaxHighlightedDiff expects. This causes an infinite setState loop (React error #185), which kills the renderer. The error boundary remounts the app, which immediately hits the same crash again.

Evidence of two triggers (from controlled testing):

State	SyntaxHighlightedDiff hits in first second	Explanation
Baseline (both triggers)	11	Two invocations amplify the loop
After replacing toolUseResult type=create with LIST format (Trigger A removed)	2	One invocation remains (Trigger B)
Removing structuredPatch/originalFile keys alone had no effect — type: "create" is the routing key, not the presence of those fields.

Secondary Bugs Found During Investigation
1. settings.local.json permission serializer stores entire heredoc content as permission strings
When the Write tool fails (e.g. WSL/Windows path mismatch) and falls back to a Bash heredoc, the full heredoc command — including the entire file content — gets serialized into settings.local.json as a permission entry. Two entries of 28KB and 24KB were found in the same session, bloating the file to 54KB.

Related issues: #15742, #16462

2. MaxListenersExceededWarning — listener leak on crash/remount cycle
Each crash-remount cycle adds a new IPC listener for AutoUpdater_$_updaterState without removing the previous one. After 11 remounts, Node.js emits a memory leak warning. This is a consequence of the crash loop, not a cause.

Suggested Fix
In SyntaxHighlightedDiff: add a guard before iterating tokens — if the language fails to load and the fallback tokenizer returns tokens without a .row property, fall back to rendering the content as plain preformatted text rather than entering the token iteration loop.

// Pseudocode
if (!token.row || typeof token.row !== 'number') {
  // render as plain text block, do not setState
  return;
}

Additionally: the markdown language grammar appears to be missing from the webview bundle entirely (the failure is not intermittent — it fires on every attempt). Either bundle it or handle the missing-grammar case before invoking the diff renderer.

Affected Files
Session JSONL: %USERPROFILE%\.claude\projects\<project-slug>\<session-uuid>.jsonl
Crash log: %APPDATA%\Roaming\Claude\logs\unknown-window.log

### What Should Happen?

It shouldn't brick claude desktop for 1... that's some pretty lousy handling if you ask me.  The error triggered only leave you the option to close the app and restart then.

### Error Messages/Logs

```shell
Claude will return soon
Claude is currently experiencing a temporary service disruption. We’re working on it, please check back soon.

Reaching out to support? Mention this error code:

1YCZHOG

Steps to Reproduce

Steps to Reproduce

  1. Start a Claude Code session in Claude Desktop
  2. Have Claude use the Write tool to create a new .md file (any markdown file that does not already exist — originalFile will be null)
  3. Close or leave the session
  4. Try to reopen the session from the sidebar

Result: Claude Desktop renders for ~1 second, then displays the crash screen ("Claude will return soon", error code 1YCzh0G). Every subsequent attempt to open the same session crashes immediately. The app must be force-quit.

---

Claude Model

Not sure / Multiple models

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.47 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

_No response_

View original on GitHub ↗

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