8000 0.41.0: crash-loop leaves orphaned MCP child processes — CPU/RAM spike (30%/3.3GB, 251 processes) · Issue #139 · amirlehmam/wmux · GitHub
[go: up one dir, main page]

Skip to content

0.41.0: crash-loop leaves orphaned MCP child processes — CPU/RAM spike (30%/3.3GB, 251 processes) #139

Closed

Description

@yatran911

Bug: wmux 0.41.0 — runaway process count / crash-loop leaves orphaned MCP child processes, huge CPU/RAM spike

Version: 0.41.0 (Windows, downgraded back to 0.38.0 as workaround)
OS: Windows 10 Pro 10.0.19045

Symptom

Shortly after updating to 0.41.0, Task Manager showed the wmux process group consuming 30.9% CPU and ~3.3 GB RAM across 251 grouped processes. Expanding the group showed it was almost entirely made of individual node.exe ("Node.js JavaScript Runtime") child processes, each relatively small (24–83 MB), but summing up massively due to sheer count. Windows Defender also flagged the sudden burst of process activity.

Screenshot of the Task Manager view (collapsed + expanded groups) available on request.

Likely root cause

Each wmux pane that runs a claude (Claude Code CLI) session spawns its own independent set of MCP-server node.exe child processes (in my setup: 6 MCP servers per session — amocrm-mcp, mpstats-mcp, imap-email-mcp ×2, mcp-google-sheets, google-tasks-mcp-server). These are not shared/reused across panes or sessions.

Between 12:38 and 13:10 (local time) on the day of the incident, 6 separate wmux crash dumps were written to %LOCALAPPDATA%\CrashDumps:

wmux.exe.3700.dmp   12:38
wmux.exe.32120.dmp  12:48
wmux.exe.22636.dmp  12:52
wmux.exe.30344.dmp  13:00
wmux.exe.18400.dmp  13:01
wmux.exe.11612.dmp  13:10

This strongly suggests wmux 0.41.0 was crash-looping — repeatedly crashing and auto-restarting (or restoring the previous session) — and on each restart it re-spawned a fresh batch of panes/CLI sessions (each pulling in its own set of MCP node child processes) without cleaning up the orphaned processes from the previous crashed instance. Over ~30 minutes this accumulated into 251 leftover node.exe processes.

Steps to reproduce (best guess, not fully confirmed)

  1. Update wmux to 0.41.0 with an existing multi-pane session that runs Claude Code (with several MCP servers configured in ~/.claude / .mcp.json).
  2. Restart / let wmux restore the session.
  3. If wmux crashes and auto-restarts (see crash dumps), observe node.exe process count climbing with each crash cycle instead of being cleaned up.

Expected behavior

  • wmux (or the terminal/pane host) should terminate child processes (including MCP server subprocesses spawned by CLI tools running in panes) when a pane/session is torn down or when wmux crashes and restarts.
  • A crash-loop should not be able to unboundedly multiply subprocess count.

Workaround

Rolled back to 0.38.0 via the cached installer left by the updater, which does not reproduce the issue.

Attachments available on request

  • Task Manager screenshot (collapsed + expanded process group)
  • Crash dump files (%LOCALAPPDATA%\CrashDumps\wmux.exe.*.dmp, ~5.3–5.8 MB each)

Activity

  1. amirlehmam commented on Aug 2, 2026

    @amirlehmam
    Owner

    Reproduced in the code and fixed — #140.

    Your diagnosis was right, including the part that matters most: the problem isn't that a crash strands processes, it's that a crash-loop multiplies them.

    What was happening

    killAll() — the only thing that tears down pane PTYs — is reachable from exactly one place, app.on('will-quit'). That doesn't run when the process dies abnormally. And Windows doesn't tear down a process tree when its root dies; descendants are reparented and keep running.

    So a crash left the whole tree resident: pane shell → claude → its six MCP servers. Nothing at the next launch looked for them, and session restore then spawned a fresh set beside the old one. Six crash cycles is exactly how you get to 251.

    The tree-kill itself was never missing. PtyManager.kill() has run taskkill /PID <pid> /T /F since #65, added precisely because Claude Code's backend orphans otherwise. It just required wmux to be alive and cooperating to reach it — which is the one thing a crash guarantees it isn't.

    The fix

    A ledger of spawned PIDs under %APPDATA%\wmux. Each spawn appends, each kill removes, killAll() clears. The next launch claims the file and tree-kills whatever a dead owner left behind.

    The delicate half isn't reaping, it's not reaping the wrong thing. That list feeds taskkill /T /F and Windows recycles PIDs, so a stale entry could take out an unrelated process and its children. A recorded PID being alive is not evidence that it's ours. Before killing anything, each PID is re-queried through Win32_Process and must still match the image name and the creation time recorded at spawn. Every failure path — no PowerShell, a query error, unparseable output — reaps nothing. Leaking a process is recoverable; killing your editor is not.

    Verified against real process trees, including that the grandchild dies (that's the MCP-server case) and that an entry whose image no longer matches is left entirely alone.

    A second, smaller thing

    Chasing your node.exe count turned up something else: every wmux hook process — Claude Code fires one per tool call, in every pane — stayed resident a full second because a stdin fallback timer was never cleared. Measured 1049 ms for work that finished in ~90 ms. Also fixed, 10× down.

    To be clear about attribution: that is not what produced your 251. The orphaning was. But it's a standing population of idle node.exe under multi-pane agent use, and it made your Task Manager view noisier than it had to be.

    What this does not fix

    The crash itself. Six .dmp files means a native crash, and I can't diagnose one from the outside.

    So yes please — I'd like the dumps. Two would be plenty (wmux.exe.3700.dmp and any later one, so I can see whether they're the same stack). The Task Manager screenshot too, if you still have it. Attach them here, or say the word if you'd rather not post them publicly and we'll sort out another route.

    Until then this change makes a crash survivable rather than cumulative — it does not stop it happening. Staying on 0.38.0 is a sensible call until we know what the crash actually is, and it would genuinely help to know whether 0.38.0 has been stable for you since, or just quieter.

  2. amirlehmam commented on Aug 3, 2026

    @amirlehmam
    Owner

    Fixed in #140, shipping in 0.42.0.

    The gap was that will-quit was the only teardown path — a crash, a
    taskkill, or an abnormal exit never reached it, so whole process trees
    (node.exe MCP children under a Claude Code PTY) survived with no parent left
    to reap them. #140 adds a PTY ledger that persists live process trees, so a
    fresh start reaps whatever the previous run orphaned rather than accumulating
    them across crash-loops.

    Note that #141 turned out to be a separate cause of main-process CPU load
    in the same version — unthrottled git.exe spawning from the diff surface. If
    you were seeing a CPU spike as well as the RAM growth, it's worth confirming
    against 0.42.0 which of the two you were hitting; the reporter there was
    correct that the process trees are unrelated (git.exe vs node.exe).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0