[Bug] Claude Desktop webview hangs on session switch with concurrent MCP server operations

Resolved 💬 22 comments Opened Apr 21, 2026 by chriscase Closed Jun 11, 2026

Bug Description
Bug: Claude Desktop webview hangs and auto-restarts when switching between Claude Code sessions

Env: Claude Desktop 1.3561.0 / CCD 2.1.111 / macOS 26.3 (25D125) / Apple Silicon / Node 24.14.0

Symptom: Window goes blank for several seconds and app auto-restarts when I switch sessions in the sidebar. 11 occurrences in ~3 days (1 on 04-19, 8 on 04-20, 2 on 04-21 by 11:14 local).

Log signature: main.log shows Main webview is unresponsive, will kill and reload followed by two Sentry captures (Main webview became unresponsive and No message, both with stack: undefined) then a full beforeQuit cleanup and relaunch.

Correlation with session switch (from ~/Library/Logs/Claude/main.log):

04-20 13:25:35 setFocusedSession → 13:25:51 unresponsive (+16s)
04-20 19:59:01 setFocusedSession → 19:59:16 unresponsive (+15s)
04-21 11:05:53 setFocusedSession + replaceRemoteMcpServers (6 servers) → 11:06:28 unresponsive (+35s)
04-21 11:13:38 setFocusedSession + session warming + 3× LocalPluginsReader.Found 2 local plugins + checkGhAvailable + getPrStateForBranch → 11:13:55 unresponsive (+17s)
Sentry event IDs (stack empty on client, but envelopes should be on your side):
2c7d8dffb09c40709a7e23d929be73af, 1f0e2cc0bb5e4c6cab380c6947be653a, 2417865d2c804b188b8fe9d72892a01c, abc7c87591764f5b85568e092ca6f8f8, e5904b50ced840e18c8e1463fb568953, 3afb8aa25b7d4994bdb9cadbf869bde0, 6ea688ea1c9e40cf860271f9048e07e0, fdc7a5d05f4f4682a228df95a19d1456, a6701a658f0d4f8f89fd72e54fadd062, 714fa2218c9c4f399af09dc3505aa87f, 05ee1e1586ce4c43a2a89c473dc8aba9.

Related macOS microstackshot (likely same code path): /Library/Logs/DiagnosticReports/Claude Helper_2026-04-17-095836_Chriss-MacBook-Pro.diag — flagged Claude Helper for 2.1 GB file-backed writes over 17h. Hot stack: v8::MicrotasksScope → node::PrincipalRealm... → temporal_rs... → cppgc → pwrite/fsync. Sustained filesystem I/O from the renderer.

Setup: 2 local Claude Code sessions on a worktree, 6 MCP servers (Claude in Chrome, mcp-registry, Claude Preview, ccd_session, ccd_directory, scheduled-tasks), 3 plugins (skills:1, local:2).

Investigation angle: The session-switch path fires a synchronous burst on focus — stopSideChat → two setFocusedSession calls (first to null) → 2–3× LocalPluginsReader → oauth token lookup → replaceRemoteMcpServers (SDK call with 6 servers) → Warming session → checkGhAvailable → getPrStateForBranch. Moving the filesystem/IPC work off the renderer main thread or spreading it across microtasks should stop Electron's hang detector from tripping.

Minor inconsistency noticed: log shows replaceRemoteMcpServers: sessionId=…, serverCount=0 but the next line passes 6 servers to the SDK — possible mislabeled log.

Happy to share main.log (~7.5 MB) if useful.

Environment Info

  • Platform: darwin
  • Terminal: Apple_Terminal
  • Version: 2.1.116
  • Feedback ID: 5d1d681b-27e7-4d06-aec5-a9190c235557

Errors

[]

View original on GitHub ↗

22 Comments

github-actions[bot] · 2 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/48300
  2. https://github.com/anthropics/claude-code/issues/37259
  3. https://github.com/anthropics/claude-code/issues/51193

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

chriscase · 2 months ago

Not a duplicate of any of those three.

vs #48300: That issue's trigger is macOS App Nap while the app is backgrounded. My events fire while the app is foregrounded and actively in use, within 15–35 seconds of clicking a different session in the sidebar. #48300's proposed fix (skip kill when window isn't focused) wouldn't help here — my window is focused throughout. Shared symptom (Main webview is unresponsive, will kill and reload), different root cause: the renderer is actually blocked doing real work on the session-switch path, not falsely flagged because of App Nap.

vs #37259: Different outcome. #37259 is about replaceRemoteMcpServers clobbering CLI plugin state — no crash, no blank screen, just state corruption. My bug does involve the same replaceRemoteMcpServers code path as one suspect in the burst, but the outcome is a full webview kill + app restart, not an MCP clobber. Related code path, different bug.

vs #51193: Different trigger and different symptom. #51193 is a mid-build token-stream stall (no crash, no reload, timer keeps running). Mine is a full Electron unresponsive → forcefullyCrashRenderer → beforeQuit → relaunch, reproducibly triggered by sidebar session switches.

See original issue body for timestamps, Sentry event IDs, and the full session-switch event chain (setFocusedSession → 2–3× LocalPluginsReader → oauth → replaceRemoteMcpServers with 6 servers → Warming session → checkGhAvailable → getPrStateForBranch, all synchronous on focus).

Feedback ID cross-reference: 5d1d681b-27e7-4d06-aec5-a9190c235557.

chriscase · 2 months ago

感谢分析,认同你说的几点。补充一些我这边的具体细节:

  1. setFocusedSession 每次切换实际上会触发两次 — 先置为 null,再设到新的 sessionId 上。相当于一次点击切换做了双倍的清理和重建工作。
  1. LocalPluginsReader 在单次切换里会被调用 3 次(同一秒内连续打印三遍 "Found 2 local plugins"),明显是重复的文件系统读取,没有任何缓存或去重。
  1. macOS 层的 microstackshot 诊断报告也佐证这个方向 — 4/17 的报告显示 Claude Helper 在 17 小时内写入了 2.1 GB 文件(35 KB/s 持续,超过系统 25 KB/s 的限制),报告最热的调用栈是:

``
v8::MicrotasksScope → node::PrincipalRealm
→ temporal_rs_PlainTime → cppgc
→ pwrite / fsync / __open
``
渲染进程在持续做同步 I/O,和切换路径上卡住的现象一致。

  1. 我这边的具体环境:两个并发的本地 Claude Code 会话,都跑在同一个 git worktree 上(\.claude/worktrees/sleepy-shannon-e453e3\)。用 worktree 的话切换时还会额外跑 \checkGhAvailable\ + \getPrStateForBranch\,比普通 repo 多一层 git 调用开销。
  1. 关于 \serverCount=0\ 的日志不一致:从日志看这个字段本身可能是记错了(实际传给 SDK 的确实是 6 个 MCP server),但如果别的代码路径也读这个 \serverCount=0\,可能会走到一些"空列表"的快速分支,那样反而会掩盖真实行为。值得查一下是只是日志字段问题,还是逻辑里也用了这个数。

如果你这边也能复现,贴一些 Sentry event ID 或者 main.log 的片段进来,应该能让这个 issue 更难被 bot 当成重复关掉。

---

English version:

Thanks for the analysis, agree with your points. Adding a few specifics from my side:

  1. \setFocusedSession\ actually fires twice on every switch — first to \null\, then to the new sessionId. So a single click-switch does double the teardown and re-setup work.
  1. \LocalPluginsReader\ is called 3 times per single switch (three consecutive "Found 2 local plugins" lines in the same second) — clearly redundant filesystem reads with no caching or dedup.
  1. A macOS microstackshot diagnostic corroborates this angle — the 4/17 report shows Claude Helper wrote 2.1 GB of file-backed memory over 17 hours (35 KB/s sustained, exceeding the system's 25 KB/s limit). Heaviest stack was:

\\\
v8::MicrotasksScope → node::PrincipalRealm
→ temporal_rs_PlainTime → cppgc
→ pwrite / fsync / __open
\
\\
The renderer is doing sustained synchronous I/O, consistent with what we see blocking on the switch path.

  1. My specific environment: two concurrent local Claude Code sessions, both on the same git worktree (\.claude/worktrees/sleepy-shannon-e453e3\). Using a worktree adds \checkGhAvailable\ + \getPrStateForBranch\ to each switch — an extra layer of git invocation overhead compared to a plain repo.
  1. On the \serverCount=0\ log inconsistency: could just be a mislabeled log field (the SDK call on the very next line passes 6 MCP servers), but if any other code path reads that \serverCount=0\, it might take an "empty list" fast path that would actually change behavior. Worth confirming whether it's only the log, or the value is also used in logic.

If you can repro on your side and paste a Sentry event ID or a main.log snippet, that would make the issue harder for the bot to auto-close as a duplicate.

chriscase · 2 months ago

更新:filed 之后约 2h15m 又触发了一次,事件链和 issue body 里的描述完全一致,serverCount=0 的不一致也再次出现:

14:08:54  LocalSessions.stopSideChat: sessionId=local_3840db9e-…
14:08:54  [CCD] LocalSessions.setFocusedSession: sessionId=null
14:08:54  [CCD] LocalSessions.setFocusedSession: sessionId=local_584b79ed-…
14:08:54  [CCD] LocalSessions.replaceRemoteMcpServers: sessionId=…, serverCount=0
14:08:54  [CCD] [replaceRemoteMcpServers] Calling SDK with 6 total servers
          (Claude in Chrome, mcp-registry, Claude Preview,
           ccd_session, ccd_directory, scheduled-tasks)
14:08:54  [LocalPluginsReader] Found 2 local plugins
14:08:55  [LocalPluginsReader] Found 2 local plugins
14:08:55  LocalSessions.getPrStateForBranch: cwd=…/worktrees/sleepy-shannon-e453e3
14:09:12  Main webview is unresponsive, will kill and reload          (+18s)

Sentry event ID: 85a78fafc6d94b98b2b4c08939c9c1df

---

English version:

Update: another crash ~2h15m after filing. The event chain matches the issue body exactly, and the serverCount=0 inconsistency reproduced too:

14:08:54  LocalSessions.stopSideChat: sessionId=local_3840db9e-…
14:08:54  [CCD] LocalSessions.setFocusedSession: sessionId=null
14:08:54  [CCD] LocalSessions.setFocusedSession: sessionId=local_584b79ed-…
14:08:54  [CCD] LocalSessions.replaceRemoteMcpServers: sessionId=…, serverCount=0
14:08:54  [CCD] [replaceRemoteMcpServers] Calling SDK with 6 total servers
          (Claude in Chrome, mcp-registry, Claude Preview,
           ccd_session, ccd_directory, scheduled-tasks)
14:08:54  [LocalPluginsReader] Found 2 local plugins
14:08:55  [LocalPluginsReader] Found 2 local plugins
14:08:55  LocalSessions.getPrStateForBranch: cwd=…/worktrees/sleepy-shannon-e453e3
14:09:12  Main webview is unresponsive, will kill and reload          (+18s)

Sentry event ID: 85a78fafc6d94b98b2b4c08939c9c1df

chriscase · 2 months ago

Update — symptom changed, root cause appears unfixed in v1.4758.0

Upgraded to Claude Desktop 1.4758.0 / CCD 2.1.119 on 2026-04-26. The original Main webview is unresponsive, will kill and reload events have stopped (the watchdog handler appears to have been loosened or removed — session switches feel smoother). But a new and worse crash mode showed up today on the same workflow:

2026-04-27 12:44:40 [info] Main webview render process gone: { reason: 'crashed', exitCode: 5 }
2026-04-27 12:44:40 [error] Sentry caught: eventId 9ca564c3edc14e209a3fd3000bc46f27

Renderer exits with code 5 (genuine crash, not a watchdog kill). The whole app terminates — does not auto-restart like the old kill and reload path did. User has to relaunch manually.

Same trigger pattern as the original issue: rapid sidebar session switches with the 6-MCP-server + 3-plugin + git-worktree config. Pre-crash log:

12:44:35  setFocusedSession: null → local_7627651e-…
12:44:35  replaceRemoteMcpServers (6 servers, serverCount=0 inconsistency still present)
12:44:35  Worktree …magical-pare-be52e8 was deleted; falling back to origin repo
12:44:35  Migrated transcript … to /…GitHub-NexaDeck
12:44:35  [Claude in Chrome] Bridge connection closed (code 1006)
12:44:37  setFocusedSession: null → local_d5b91ff9-…   ← second switch within 2s
12:44:37  replaceRemoteMcpServers (6 servers)
12:44:40  Main webview render process gone, exitCode 5 ← +3s after switch #2

Possibly relevant disk-I/O regression — macOS filed a microstackshot against the new version on 04-26 for 8.6 GB of file-backed writes in 37 minutes (3.8 MB/s sustained). The previous version was flagged at ~35 KB/s sustained. That's roughly 110× more sustained write activity in 1.4758.0 — could be starving the renderer enough that the underlying main-thread blocking now manifests as an outright crash instead of a watchdog kill.

Net: removing the watchdog kill+reload doesn't fix the underlying main-thread-blocking issue on session switch — it just changes the failure mode from "blank screen and recover" to "full app termination." The serverCount=0 log inconsistency is still present too.

Sentry event ID for this incident: 9ca564c3edc14e209a3fd3000bc46f27. Happy to share more log timestamps or a fuller window on request.

chriscase · 2 months ago

Another crash, same signature — fresh repro

2026-04-29 08:02:53  [CCD] LocalSessions.setFocusedSession: sessionId=null
2026-04-29 08:02:53  LocalSessions.getPrStateForBranch: cwd=…/NexaDeck, branch=main
2026-04-29 08:02:53  [CCD] LocalSessions.setFocusedSession: sessionId=local_927ef9f1-…
2026-04-29 08:02:53  [LocalPluginsReader] Found 2 local plugins
2026-04-29 08:02:54  [CCD] LocalSessions.replaceRemoteMcpServers: sessionId=…, serverCount=0
2026-04-29 08:02:54  [CCD] [replaceRemoteMcpServers] Calling SDK with 7 total servers
                       (Claude in Chrome, mcp-registry, Claude Preview,
                        ccd_session, ccd_directory, ccd_session_mgmt, scheduled-tasks)
2026-04-29 08:02:58  Main webview render process gone: { reason: 'crashed', exitCode: 5 }   ← +5s after switch
2026-04-29 08:02:58  Sentry caught: eventId 4055bda86fbe471c9dbf5bb861036fc1

New detail: I've added a 7th MCP server (ccd_session_mgmt) since the last update, and the crash still triggers the same way — switch session in sidebar, replaceRemoteMcpServers fires with 7 servers, renderer is dead within 5s.

The serverCount=0 log inconsistency I flagged in the original body is still present in 1.4758.0 / 2.1.119 even though 7 servers actually get passed to the SDK on the very next log line. Worth checking whether anything reads that field in logic, not just in the log message — could be why this code path is doing something wrong on the focus transition.

App version still Claude Desktop 1.4758.0 / CCD 2.1.119, macOS 26.3 / Apple Silicon. Sentry event ID: 4055bda86fbe471c9dbf5bb861036fc1.

chriscase · 2 months ago

Clarification on MCP server count: I'm not adding these manually

After looking at this more carefully, I want to flag that none of the 7 MCP servers passed to the SDK on session switch are user-installed. My ~/Library/Application Support/Claude/claude_desktop_config.json has no mcpServers section at all — the entire file is just { "preferences": { ... } }.

All 7 are auto-registered by Claude Desktop / CCD itself:

| Server | Source |
|---|---|
| Claude in Chrome | Auto-registered when a Chrome extension is paired ([Claude in Chrome] MCP server registered at startup). |
| mcp-registry | Built-in to Desktop. |
| Claude Preview | Built-in to Desktop. |
| ccd_session | Built-in to CCD. |
| ccd_directory | Built-in to CCD. |
| ccd_session_mgmt | New in 1.4758.0 / CCD 2.1.119 — added automatically by the 04-26 update. |
| scheduled-tasks | Gated on built-in preferences (ccdScheduledTasksEnabled, coworkScheduledTasksEnabled). |

The bump from 6 → 7 between my earlier comments wasn't me adding a server — it's ccd_session_mgmt being shipped by the Desktop update on 04-26. So the session-switch-burst code path is doing strictly more synchronous work on focus with each Desktop release, for any user with a default install. The crash hasn't been caused by my config drifting; it's been getting worse on its own as new built-in servers ship.

That also means most of these can't be turned off by the user as a workaround — only Claude in Chrome (unpair extension) and scheduled-tasks (preference toggle, loses functionality) are actually user-disable-able. The other five are load-bearing for the Desktop feature set.

Worth keeping in mind when prioritizing the fix: the trend is more servers per release on a code path that already over-serializes them.

chriscase · 2 months ago

Crash #4 — same signature, possible new contributing error

27 minutes after the previous crash (9ca564c3edc14e209a3fd3000bc46f27 at 08:02:58), another one at 08:30:15 with the same render-process-gone exit code 5. Pre-crash log shows a PreviewError thrown one second before the renderer dies:

2026-04-29 08:30:14  [CCD] LocalSessions.setFocusedSession: sessionId=null
2026-04-29 08:30:14  [CCD] LocalSessions.setFocusedSession: sessionId=local_a4b346f0-…
2026-04-29 08:30:14  [warn] [Preview] capturePreviewScreenshot failed:
                       PreviewError: Preview not found for server baf43587-ceb6-41fe-8f4c-fe30e6a5f822
                       code: 'NOT_FOUND'
2026-04-29 08:30:14  [LocalPluginsReader] Found 2 local plugins
2026-04-29 08:30:14  [CCD] LocalSessions.replaceRemoteMcpServers: serverCount=0
                       Calling SDK with 7 total servers (Claude in Chrome, mcp-registry,
                       Claude Preview, ccd_session, ccd_directory, ccd_session_mgmt,
                       scheduled-tasks)
2026-04-29 08:30:14  LocalSessions.getPrStateForBranch (branch=main)
2026-04-29 08:30:14  LocalSessions.getPrChecks: prNumber=696
2026-04-29 08:30:15  Main webview render process gone, exitCode 5    ← +1s

The PreviewError is a [warn]-level on a missed preview screenshot for an unknown server (baf43587-ceb6-41fe-8f4c-fe30e6a5f822), not obviously fatal in isolation — but it's firing inside the same session-switch burst as everything else. Worth checking whether an unhandled rejection or error swallow on that path could be contributing to renderer instability when combined with the rest of the focus-time work.

Sentry event ID: d9bc3997e04a4852958f2dee841e68ef. Running totals on Claude Desktop 1.4758.0 / CCD 2.1.119:

  • 04-26: 1 crash
  • 04-27: 1 crash
  • 04-29: 2 crashes (so far, by 08:30 local)
chriscase · 2 months ago

Crash #5 — confirms rapid-switch pattern

Third crash today (08:40:33). User observation: "seems to crash if I switch sessions quickly" — log confirms it cleanly. Two session switches in 5 seconds, renderer dies 3 seconds after the second switch:

08:40:25  setFocusedSession: null → local_a4b346f0-…    ← switch #1
08:40:25  replaceRemoteMcpServers (7 servers, serverCount=0)
08:40:30  setFocusedSession: null → local_927ef9f1-…    ← switch #2 (+5s)
08:40:30  replaceRemoteMcpServers (7 servers, serverCount=0)
08:40:33  Main webview render process gone, exitCode 5  ← +3s after switch #2

This is now the third reproduction of the same back-to-back-switch → crash pattern:

| Date/time | Switch #1 | Switch #2 | Crash | Sentry event |
|---|---|---|---|---|
| 04-27 12:44:35–40 | 12:44:35 | 12:44:37 (+2s) | 12:44:40 (+3s) | 9ca564c3edc14e209a3fd3000bc46f27 |
| 04-29 08:30:14–15 | (single switch but with PreviewError in chain) | — | 08:30:15 (+1s) | d9bc3997e04a4852958f2dee841e68ef |
| 04-29 08:40:25–33 | 08:40:25 | 08:40:30 (+5s) | 08:40:33 (+3s) | ff05ed8cc11f465a9fe8b4ab2a1f35b8 |

The single-switch crash on 08:30:15 is the outlier — but it had the PreviewError thrown in the same second. So the pattern looks like: anything that causes a second burst of replaceRemoteMcpServers work to overlap with the first burst is sufficient to crash the renderer. A second click in <~10 seconds does it; a PreviewError exception thrown into the chain seems to do it too.

If the renderer is genuinely starved by the synchronous I/O on focus (consistent with the 3.8 MB/s sustained-write microstackshot from 04-26), then a second replaceRemoteMcpServers invocation while the first one is still running would push it over the edge — a debounce or cancellation on focus changes, or a guard that no-ops replaceRemoteMcpServers when the previous call hasn't drained yet, would likely eliminate the rapid-switch crash class.

Running totals on Claude Desktop 1.4758.0 / CCD 2.1.119:

  • 04-26: 1
  • 04-27: 1
  • 04-29: 3 (so far, by 08:40 local — three within 38 minutes)
chriscase · 2 months ago

Crash #6 — full process termination (more severe than recent crashes)

User reports another Claude Code Desktop crash at approximately 2026-04-30 00:35 UTC (≈ 17:35 local PT). This time the process terminated entirely — not the blank-screen-but-app-still-running variant of Crashes #1–#3, but a full app death like Crash #4 (matching the more severe failure mode noted in the comment thread above on 2026-04-29 around session #4).

So now in this 12-hour window we have:

  • Crashes #1, #2, #3, #5: blank-screen / webview hang (process survives, UI dead)
  • Crashes #4, #6: full process termination (app gone from Activity Monitor)

Both modes are still happening on v1.4758.0. The mix is roughly 4:2 — blank-screen is more common but full terminations are not rare.

That two distinct failure modes coexist suggests there may be two related bugs (e.g. a renderer hang AND a main-process crash) sharing a common trigger (session-switch + concurrent MCP work), rather than one bug that always presents the same way. Worth keeping in mind when prioritizing the fix.

No fresh logs captured this time — user reported conversationally. Happy to capture a log on the next process-termination repro if it would distinguish "renderer SIGKILL" from "main process panic."

chriscase · 2 months ago

Crash #7 — recurrence ~5h after #6

Another Claude Code Desktop crash at approximately 2026-04-30 05:37 UTC. Same general pattern, no new diagnostic capture.

Updated count: 7 crashes in ~17h on v1.4758.0. Recurrence rate stable. Mix continues to span both blank-screen and full-process-termination modes (see comment above for the breakdown).

No fresh logs this time — happy to capture a feedback-ID-tagged log on the next repro if it would distinguish anything you haven't already isolated from the earlier traces.

chriscase · 2 months ago

Crash #8 — recurrence ~12.5h after #7

Another Claude Code Desktop crash at approximately 2026-04-30 18:03 UTC (~11:03 local PT). Same general pattern, no specific repro details captured.

Updated count: 8 crashes in ~30h on v1.4758.0. Recurrence rate is now roughly one every 3.5–4 hours of active multi-session use. Mix continues to span both blank-screen and full-process-termination modes (see comment from 2026-04-30 00:35 UTC for the breakdown).

Going to keep noting these as they happen so the recurrence cadence is documented. Happy to capture a feedback-ID-tagged log on the next repro if it would distinguish anything you haven't already isolated from the earlier traces.

chriscase · 2 months ago

Crash #9 in this session.

Lost context mid-implementation of AbydonianSupport #78 (Crashes → Events rename + SSE live-streaming mode). Was actively in the middle of:

  • Renaming apps/web/src/app/[locale]/admin/crashes/events/ via git mv (just completed the move; contents still need internal renames)
  • Just discovered a real wiring bug in NexaDeck: crash::identity::collect() hardcodes abydonian_user_id and account_email to None despite OAUTH_USER_EMAIL being available in licensing::commands. User noticed this when testing — they were signed in but their crashes still showed "(not signed in)".
  • About to wire that up + continue the rename PR.

Same session, repeated context losses. Compaction is recovering most context but each crash costs 5-10 minutes of rebuild time.

chriscase · 2 months ago

Crash #10 in this session.

Last completed before crash: shipped AbydonianSupport #78 (Crashes → Events rename + SSE live-streaming mode, PRs #80 + #81 merged + deployed) + NexaDeck #778 (OAUTH_USER_EMAIL → crash identity wiring, merged to main).

Was at a natural handoff point — had recommended two follow-ups (capture OAuth sub claim for abydonian_user_id; per-customer admin aggregation view) and asked the user if they wanted me to file/ship them. Now picking back up by checking branch state and continuing.

Tenth crash this session. Cumulative cost: an hour-plus of rebuild time. The compaction recovery is reliable but each rebuild reads the prior PR/issue history and the current git state, so each is non-trivial.

chriscase · 2 months ago

Crash #11 in this session.

Last completed before crash: shipped AbydonianSupport #82 + PR #83 (per-customer aggregated profile view at /admin/customers, transitive-closure walk on CrashIdentity) deployed to production. Smoke tests passed (page returns 200, customerProfile resolver gated by staff auth). Sister NexaDeck #779/#780 already merged — captures OAuth sub claim → abydonian_user_id.

State at crash: clean handoff point. Both major follow-ups complete + deployed. Auto mode still active; user said "continue".

Eleven crashes this session. Each compaction-recovery cycle is reliable but takes 5-10 minutes to rebuild context from PR/issue history + git state.

chriscase · 2 months ago

Crash #12 in this session.

Last completed before crash: shipped AbydonianSupport PR #84 (customer-lookup search widget in admin top bar — small UX follow-up to #82) merged + deployed to production. Smoke tests passed.

Pattern observation across 12 crashes in this single session:

  • Crashes cluster around long-context conversations (heavy PR/issue history reads, multi-repo work)
  • Compaction recovery is reliable — but each cycle costs 5-10 minutes of context rebuild
  • The same session has been productive (~12 PRs merged + deployed, ~8 GitHub issues filed) but momentum is constantly being lost

User is increasingly frustrated. Quoting verbatim: "claude code crashed AGAIN, what was it this time!?!?!?!?!?!?!??!"

Cumulative cost in this session alone: probably 1-2 hours of rebuild time across crashes, plus the productivity friction of constantly re-establishing where we are.

chriscase · 2 months ago

Crash #12 in this session — same trigger as the hang signature in this issue, but now the renderer is actually crashing rather than just hanging. macOS, Desktop 1.5354.0 / CCD 2.1.121.

Fresh log signature (clean, repeatable shape):

2026-05-01 00:59:23 [info] [CCD] LocalSessions.setFocusedSession: sessionId=null
2026-05-01 00:59:23 [info] [CCD] LocalSessions.setFocusedSession: sessionId=local_e5933343-f958-429a-9c2f-13801ab1977e
2026-05-01 00:59:24 [info] [LocalPluginsReader] Found 2 local plugins
2026-05-01 00:59:24 [info] [CCD] LocalSessions.replaceRemoteMcpServers: sessionId=local_e5933343-..., serverCount=0
2026-05-01 00:59:24 [info] [CCD] [replaceRemoteMcpServers] Calling SDK with 7 total servers {
2026-05-01 00:59:26 [info] Main webview render process gone: { reason: 'crashed', exitCode: 5 }
2026-05-01 00:59:26 [error] Sentry caught: {
  eventId: 'fd702299fdcd45b98cb609c5e7ae17ae',
  type: 'Unknown',
  value: 'Main webview render process gone',
  stack: undefined
}

Sequence:

  1. Session focus changes (null → local_xxx) at 00:59:23
  2. replaceRemoteMcpServers SDK call fires at 00:59:24 with 7 total servers
  3. 2 seconds later the renderer is gone with exitCode 5
  4. Sentry catches the loss but reports type: Unknown / stack: undefined — same un-typed-throw pattern documented in #55220

This happened twice in 33 minutes today on the same machine: 00:26:59 and 00:59:26. Both times preceded by replaceRemoteMcpServers with a non-zero serverCount in the log line right before. Both produced the same un-typed Sentry event.

exitCode 5 is the same exit code documented in #54369, though that issue is about getPrStateForBranch on worktree paths — different trigger. Cluster of related symptoms: focus-change + MCP-server-replacement + renderer-process-going-down.

Sentry event IDs from today (so engineers can pull stacks directly):

  • 4112caafb0134a82a226583ea8968dc6 (00:26:59)
  • fd702299fdcd45b98cb609c5e7ae17ae (00:59:26)
  • 01531d35e04d4b8faa6e90b47df5681c, 7dddac5834584b5b87c6af35e0c31637, ee7448306eeb49c28a018c3438b7ed46, 6196fbbfe3e34b9d98c161220f4c409a (00:27:17 burst — see #55220)

What changed about the trigger over time: today the user is running 7 MCP servers (Claude in Chrome, Claude Preview, ccd_session, ccd_session_mgmt, ccd_directory, scheduled-tasks, mcp-registry) plus 2 local plugins. Higher MCP-server count seems to correlate with higher crash frequency in replaceRemoteMcpServers, which fits the original issue title.

This is now Crash #12 in a single working session (cumulative ~hour-plus of rebuild-from-compaction time). The session-switch path is the highest-frequency path through the crash, by a wide margin.

chriscase · 2 months ago

Crash #13 in this session — third occurrence of the replaceRemoteMcpServers → exitCode 5 pattern in under 1 hour (00:26:59, 00:59:26, 01:22:22). Important new detail this time:

No active agents, no in-flight tool calls, no model activity at all. User just clicked the session in Desktop. The crash happened purely from the session-warm path.

Fresh log signature (the 30-second window before crash):

2026-05-01 01:22:19 [info] [CCD] LocalSessions.setFocusedSession: sessionId=null
2026-05-01 01:22:19 [info] [CCD] LocalSessions.setFocusedSession: sessionId=local_d5b91ff9-...
2026-05-01 01:22:19 [info] [CCD] Warming session local_d5b91ff9-...
2026-05-01 01:22:19 [info] LocalSessions.checkGhAvailable: cwd=/Users/chriscase/Documents/GitHub
2026-05-01 01:22:19 [info] [CCD] LocalSessions.replaceRemoteMcpServers: sessionId=local_d5b91ff9-..., serverCount=0
2026-05-01 01:22:19 [info] [CCD] Passing 3 plugin(s) to SDK (skills: 1, remote: 0, local: 2)
2026-05-01 01:22:19 [info] [CCD] Session local_d5b91ff9-... warmed successfully in 492ms
2026-05-01 01:22:22 [info] Main webview render process gone: { reason: 'crashed', exitCode: 5 }

Note serverCount=0 — the earlier comment hypothesized that higher MCP server counts correlate with crash frequency. That hypothesis is wrong: even a replacement with zero net servers triggers the crash. The trigger is the session-warm cycle itself, independent of MCP load.

What this rules in vs out:

  • ❌ NOT agent / tool / model activity (no agents running)
  • ❌ NOT MCP server count (crashed at 0 servers AND at 7 servers, same shape)
  • ❌ NOT user-initiated work (user just clicked the session)
  • ✅ DOES correlate with setFocusedSession + replaceRemoteMcpServers + Warming session SDK call cycle
  • ✅ DOES correlate with going from sessionId=null → focused session
  • ✅ Crash consistently arrives ~3 seconds after Session warmed successfully

Sentry event IDs from this latest burst:

  • fd457b5d3e274d019bdc3716ec6172cc
  • 43c36984a32545e48e19370923d07156
  • 1697afc871c140d68d450762668df716

Cumulative event IDs across today (12 documented Claude-Desktop crashes in this single user session):

  • 00:26:59 — 4112caafb0134a82a226583ea8968dc6
  • 00:27:17 burst — 01531d35e04d4b8faa6e90b47df5681c, 7dddac5834584b5b87c6af35e0c31637, ee7448306eeb49c28a018c3438b7ed46, 6196fbbfe3e34b9d98c161220f4c409a (also #55220)
  • 00:59:26 — fd702299fdcd45b98cb609c5e7ae17ae
  • 01:22:22 — fd457b5d3e274d019bdc3716ec6172cc, 43c36984a32545e48e19370923d07156, 1697afc871c140d68d450762668df716

Suggested narrowing for triage: focus on the session-warm path that runs immediately after setFocusedSession with a sessionId transition from null → real. The crash arrives ~3 seconds after warmed successfully returns. Whatever runs between "warm complete" and "renderer dies" is where the un-typed throw originates. The fact that no model / agent activity is required to trigger the crash should make repro on Anthropic side straightforward: just rapidly toggle session focus on a machine with multiple Claude Code sessions.

hooolio · 2 months ago

Claude Desktop thinks I'm hitting this issue too:

Windows with v1.6259.1.0 (MSIX). Two full-app restarts within ~50 minutes of each other, plus a triple cowork-search Utility crash that the app self-recovered from.

Environment

Claude Desktop: 1.6259.1.0 (MSIX / Microsoft Store, package family Claude_pzs8sxrjxfjjc)
CCD: 2.1.128
Node: 24.15.0
OS: Windows 11 Pro 26200 x64
MCP server count: 38 (mix of plugin-bundled local + 7 remote)
Trigger correlation: Crashes started right after I began using Ctrl+Tab / Ctrl+Shift+Tab to navigate between sessions in the sidebar. Both crashes were immediately preceded by a tight cluster of session-PTY teardowns, matching the "synchronous burst" path called out in the original report.

Log signature in main.log (crash 1):

17:59:06 [info] Shell PTY for session <id-A> exited (stale — already replaced)
17:59:06 [info] Shell PTY for session <id-B> exited (stale — already replaced)
17:59:06 [info] Shell PTY for session <id-C> exited (stale — already replaced)
17:59:06 [info] Shell PTY for session <id-D> exited (stale — already replaced)
17:59:06 [warn] claudeURLHandler: invalid protocol 'c:'
17:59:06 [warn] claudeURLHandler: invalid protocol 'c:'
<~29s gap, no further log output>
17:59:35 [info] Starting app { appVersion: '1.6259.1', ... }
17:59:35 [error] Sentry caught: { eventId: '60a43fa8c5b54680b7f3acb41b20e0a2', type: 'Unknown', value: 'No message', stack: undefined }
Same fingerprint for crash 2 at 18:48:03 (Sentry eventId ae642152e6e64bd3860783be221d62bb). The value: 'No message', stack: undefined event is consistent with Electron's watchdog killing an unresponsive webview before any JS-level handler runs.

Adjacent subprocess instability (possibly related): the cowork-search Utility process has been dying repeatedly on this version. Today alone: 'Utility' process exited with 'killed' at 07:01, 07:31 (×2), 10:07, plus a triple 'Utility' process exited with 'crashed' cluster at 18:23:37 immediately preceded by [cowork-search] worker exited (4294967295); will refork on next search. The app auto-recovered from those without a full restart. Sentry event IDs for the 18:23:37 cluster: ad6aee05fd364edba2b3672394a8357b, 8e0869f2a4a7479f95c723c0426b9d0a, 93d6c3d99391421da021d615fbc95054.

claudeURLHandler: invalid protocol 'c:' warning: appears right before crash 1. Looks like a Windows-style path (C:\...) being parsed as a URL with protocol c:. May or may not be related, but flagging in case it points at the same code path.

Workaround being tried: switch sessions via mouse click instead of Ctrl+Tab.

chriscase · 2 months ago

Thanks for the cross-platform repro — useful for triage even though, as you'd expect from an Electron app, the renderer / PTY teardown coordination doesn't really care about OS.

What lines up between our reports:

  • Same Sentry fingerprint pattern (type: Unknown, stack: undefined)
  • Both triggered by rapid session-focus changes — yours via Ctrl+Tab keyboard navigation, mine via sidebar clicks while MCP servers are reconciling
  • ~29s gap between the PTY teardowns and the next log line in both reports, consistent with Electron's watchdog killing an unresponsive renderer before any JS-level handler can fire
  • Bug survives ≥7 patch releases — you're on CCD 2.1.128; I've worked through 2.1.121 → 2.1.128 with no observable behavior change

What differs (and helps narrow the cause):

  • Different OS (Windows vs macOS) — rules out OS-specific focus event handling as the proximate trigger
  • Different installer (MSIX vs DMG) — rules out packaging
  • Different MCP set (yours: 38, mostly plugin-bundled; mine: ~5–8, mostly remote) — rules out a specific server's behavior

Side note on your claudeURLHandler: invalid protocol 'c:': that's almost certainly a Windows path (C:\...) being passed to URL-parsing code, where the leading c: reads as a scheme. Looks like a real Windows-specific bug regardless of whether it's the crash trigger here, and possibly worth its own issue if you have the bandwidth — could be claude-protocol deeplink handling getting Windows-path inputs somewhere.

Cross-references for whoever picks this up: #54369 tracks the renderer SIGTRAP as observed from the Electron main process (Main webview render process gone, exitCode: 5); #55220 tracks the same event as observed downstream of Sentry forwarding. wsalem117's analysis on #48281 fingers V8 OOM during transcript loads as the underlying mechanism — fits the "no JS message, no stack" signature, since the renderer's V8 isolate is already gone by the time the watchdog kicks in.

I'll experiment with reducing rapid focus changes (your Ctrl+Tab workaround applied to my sidebar-click pattern) and report back if it shifts the crash cadence on macOS.

chriscase · 2 months ago

Update — same pattern: the renderer SIGTRAP (#54369) and likely the Sentry burst (#55220) appear fixed in 1.6259.1+. My last Main webview render process gone was 2026-05-02 23:45:29 on 1.5354.0; nine days of heavy session-switching + concurrent-MCP work since, across three version upgrades (1.6259.1 → 1.6608.0 → 1.6608.2), zero recurrences.

The Ctrl+Tab and rapid-session-switch triggers @hooolio and I both identified would normally have fired this multiple times by now. Worth a verification pass on Windows MSIX builds too, since the underlying fix may have shipped via the shared Electron pipeline.

Not closing yet; will let more time pass before doing that. Flagging as positive triage signal.

github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.