VS Code Extension 2.1.204 hangs for 90+ seconds every 30-40 min (macOS ARM64) — native process correctly idle in kevent64

Status Open
Reported on v2.1.204
Maintainer reply None cached
Activity 14 comments · opened Jul 8, 2026

Bug Report: Claude Code VS Code Extension Hangs After 30-40 Minutes (macOS ARM64)

Summary

Claude Code VS Code extension reproducibly hangs/freezes for 90+ seconds every 30-40 minutes of use, with the native claude subprocess correctly idling in kernel wait (kevent64). The hang occurs across multiple different projects, not specific to any single codebase. The extension and IDE remain responsive—the freeze appears upstream in the extension host's IPC/event-loop layer.

Environment

  • Extension version: 2.1.204 (build tag: cc_version=2.1.204.d9b)
  • Internal build path: ~/.vscode/extensions/anthropic.claude-code-2.1.204-darwin-arm64
  • macOS: 26.5.1 (build 25F80)
  • Hardware: Apple Silicon (Mac16,10, ARM64), 16GB RAM, 10 CPU cores
  • Standalone CLI version: 2.1.85 (separate install)

Symptom

Single VS Code window with single Claude Code tab hangs for 90+ seconds, blocking the chat panel from responding. Then resumes cleanly with no restart or state loss. Occurs repeatedly across multiple projects and multiple sessions over a period of weeks.

Typical hang sequence:

  1. User working normally for ~30-40 minutes
  2. Claude Code UI freezes (chat panel unresponsive, webview spinner halts)
  3. Native log file shows 90-96 seconds of complete silence between log messages
  4. System remains responsive (not OS-level freeze)
  5. Extension spontaneously resumes without user intervention
  6. No error messages logged before or after the freeze

Forensic Evidence

1. Extension Log Silence

The Claude VSCode extension's own debug log (~/Library/Application Support/Code/logs/<timestamp>/window*/exthost/Anthropic.claude-code/Claude VSCode.log) contains a genuine 599-second gap of complete silence between two routine, unrelated update_session_state webview messages. No errors logged before or after the freeze.

2. VS Code Watchdog Did NOT Fire

VS Code's built-in extension host unresponsiveness detector (fires when one extension blocks the shared Node.js event loop for ~10+ seconds) never triggered. This rules out the classic "another extension is hogging the shared event loop" scenario.

3. Native Process Stack Sampling (5 Independent Captures)

A background watchdog monitoring the extension's own log file for silence detected and captured five separate hangs (silence durations 92s, 96s, 96s, 96s, and 96s, across a ~90 minute window) using macOS's sample(1) tool. Stack traces from all five show the identical pattern:

Main thread behavior (~95-98% of samples):

  • Thread: DispatchQueue_1: com.apple.main-thread (serial queue)
  • All samples stack at: kevent64 in libsystem_kernel.dylib
  • This is a legitimate blocking kernel wait, not a busy-loop or spin
  • Conclusion: The native claude binary is correctly idle, waiting for I/O/events

Recurring side-branch (~2-6% of samples, single-digit to ~90 count):

  • Appears at nearly identical binary offsets across all five independent captures, taken minutes to tens of minutes apart
  • Example offsets: +0x75fdac+0x275a584+0x278e7fc+0x277dce8
  • This suggests a specific periodic callback/timer that runs consistently during the freeze
  • The work done by this branch does NOT wake/resolve the main response path
  • Binary is stripped (no symbols), so function identity unknown, but pattern is consistent

4. Memory Footprint Normal

Physical memory footprint of claude process during all five hangs:

  • Hang 1: 201.0 MB (peak 216.0 MB)
  • Hang 2: 201.1 MB (peak 216.0 MB)
  • Hang 3: 278.6 MB (peak 293.1 MB)
  • Hang 4: 173.3 MB (peak 191.3 MB)
  • Hang 5: 211.0 MB (peak 226.0 MB)
  • System-wide memory pressure was not critically high during these hangs

This rules out memory bloat or OOM-adjacent behavior in the native process as the cause of these hangs.

5. Capture Files

Raw forensic data (stack dumps + memory/CPU snapshots) for all five hangs is attached as a gist:
https://gist.github.com/terrancedjones/6f4bb89b7e298ec65109d0ae17e6af5e

Each file contains: full sample(1) output, vm_stat, sysctl vm.swapusage, and ps aux sorted by memory for the time window.

Root Cause Analysis

The evidence points away from the native binary itself and toward the extension host's IPC/event-loop layer:

  • Native claude subprocess is legitimately waiting (kevent64) for events/input
  • Memory footprint is normal (not leaking)
  • The periodic side-branch suggests some timer/callback is running, but it's not waking the stalled wait
  • This indicates the extension host's TypeScript/JS code or the webview (chat panel UI) renderer is not feeding events to the native process when it should be

The hang is likely caused by:

  1. A deadlock or event-loop stall in the extension host between the webview and the native subprocess's stdio/IPC channel
  2. A missing wakeup signal after a specific operation
  3. A resource contention issue (file lock, pipe buffer, etc.) in the IPC layer
  4. A timer/polling mechanism that's checking for input but not actually reading it

Steps to Reproduce

Difficult to reproduce on demand, but consistent over weeks:

  1. Open Claude Code VS Code extension
  2. Work normally in a single tab for ~30-40 minutes
  3. Observe: chat panel freezes, extension log shows 90+ second silence
  4. Wait ~5 minutes: extension resumes without action

Workarounds (Known)

  • No intervention needed — all 3 captured hangs self-resolved within ~90-100 seconds with no restart, crash, or lost session state (confirmed directly from the watchdog's "log activity resumed" timestamps)
  • Reloading the VS Code window is not required to recover, though a user who doesn't know it will self-resolve may reasonably reach for it out of frustration

Related Known Issues

This may be related to or a variant of:

  • Issue #30417 (VS Code Extension hangs indefinitely on macOS ARM64)
  • Issue #25976 (Dual process spawn with MCP server errors)
  • Issue #39381 ("Not responding - try stopping" with no recovery mechanism)

Suggested Next Steps for Maintainers

  1. Check the extension host's stdio/pipe buffer handling during idle periods
  2. Review event-loop wake conditions between the webview renderer and native subprocess IPC
  3. Add explicit timeout/heartbeat detection to the extension's native process communication layer
  4. Profile the ~2-6% recurring side-branch function using non-stripped binaries to identify the periodic callback
  5. Consider whether kevent64 is the right wait primitive or if there's a race condition in how events are polled

Additional Context

  • This is not a single-project issue (happens across PropertyHunter-Go, PropertyHunter-React, and other repositories)
  • This is not a memory pressure issue (system was healthy during the hangs)
  • This is not a CLI issue (the CLI was updated to 2.1.85 but the extension hangs persist at 2.1.204)

View original on GitHub ↗

13 Comments

terrancedjones · 1 month ago

Update: investigated apparent project-specificity

Follow-up after further discussion with the reporter. Initially this looked like it happened across multiple projects on the same machine; on closer questioning, the reporter clarified the hang has actually only been observed in one specific project (this one), out of 5 they regularly work in on the same machine.

Ruled out as explanations for that difference:

  • Repo size/file count: this project (1,809 Go files, 4,026 tracked files) is smaller than at least one of the reporter's other projects (2,401 Go files, 10,260 tracked files) that does not exhibit the hang — so raw workspace size isn't it.
  • Multi-root workspace setup: this project is opened together with its companion frontend repo (via Claude Code's --add-dir) — confirmed the reporter uses the identical dual-repo setup across all their projects, not just this one.
  • Project-specific VS Code config: no unusual tasks.json, no hooks, standard file-watcher excludes already in place.

One confirmed difference: this is the project where the reporter runs their longest and most agent/tool-call-intensive sessions (multi-agent orchestration workflows involving many parallel subagent spawns). Their other projects tend to get shorter, lighter sessions.

Given the hang only manifests after ~30-40 minutes of continuous activity in every captured instance, the simplest explanation is that this isn't project-specific in mechanism — it's exposure-dependent. This project happens to be where session duration / cumulative tool-call volume most reliably crosses whatever internal threshold triggers the stall. Other projects may simply not run long/heavy enough sessions to hit it as often (or at all, so far).

If there's a counter or accumulator in the extension host tied to session duration, tool-call count, or subagent spawn count, that would be consistent with this pattern and might be a productive place to look.

terrancedjones · 1 month ago

Correction to previous comment

The "longer/heavier sessions" hypothesis in my prior comment was incorrect — confirmed directly with the reporter that all their projects run comparable session durations (~40 min), not just this one. Retracting that specific explanation; the session-duration/tool-call-volume theory doesn't hold up as the differentiator.

Still investigating what's actually different about this project vs. the reporter's other 4. Will follow up with verified findings rather than another guess.

terrancedjones · 1 month ago

Major update: likely root cause found — contention on shared ~/.claude.json

While actively monitoring multiple concurrent Claude Code sessions across different projects on the same machine, we caught a hang in progress (not just after-the-fact) and captured a live stack sample while it was still frozen.

Key finding: the last line logged by the frozen session, immediately before the freeze, was:

[DEBUG] Renaming /Users/<user>/.claude.json.tmp.<pid>.<random> to /Users/<user>/.claude.json
[DEBUG] File /Users/<user>/.claude.json written atomically

~/.claude.json is a single shared file used by every Claude Code session on the machine, across every project — not a per-project or per-session file. At the time of this hang, at least 3 Claude Code sessions were running concurrently across 2 different projects, each independently performing this same atomic write pattern (write to a PID-specific temp file, then rename over the shared target).

This is a plausible explanation for several things that were previously puzzling:

  • Why the hang isn't actually project-specific (contrary to what we initially reported) — the contended resource is global, not scoped to any one project.
  • Why it correlates with having multiple simultaneous tabs/windows open rather than with any particular project's code, size, or config.
  • Why reinstalling the extension doesn't help — the shared file and the multi-process access pattern exist independently of the extension's own installed code.

This specific hang was notably more severe than the ~90-100s hangs previously reported: it remained frozen for 19+ minutes with no self-recovery (all previously captured hangs self-resolved within ~90-100 seconds). The live stack sample during this longer freeze still showed the same kevent64 blocking-wait pattern as before — so whatever is stuck, it's still a legitimate wait, not a spin — but this time nothing woke it for a much longer period. No leftover .tmp file was found (so the write itself wasn't left mid-flight), and lsof showed no active lock holder on the file at the time we checked, which suggests the stall is upstream of the raw file I/O — possibly in whatever coordinates read-modify-write access to that shared file across concurrent processes (e.g., waiting on another session's in-progress read-modify-write cycle, or a lock/mutex implemented above the filesystem layer).

Suggested next step for maintainers: look at what serializes or coordinates writes to ~/.claude.json across concurrent claude processes (if anything does), particularly under 3+ simultaneous sessions across different project directories. If there's an in-process or cross-process lock guarding this file, a stuck/leaked lock or a missing timeout on lock acquisition would fit all observed symptoms exactly.

terrancedjones · 1 month ago

Correction + sharper finding: hang occurs with zero user interaction, confirmed in a second, unrelated project

Correcting imprecision in my last update: the hang I reported as "happening in EngageHunter-React" needs a more careful description, and the corrected version is actually a stronger signal.

Checked the full extension log for that window (751 lines, covering ~6 hours):

  • The extension host itself started fresh at a specific time and immediately auto-resumed a pre-existing, already-idle session (a session the user confirms they had not sent any new messages to in over 48 hours) — working directory .../EngageHunter-Go (a different project from the one in earlier reports), with a companion frontend repo added as a secondary directory (same backend+frontend pairing pattern as the original report, different codebase).
  • Searched the entire log for any actual user-originated chat message (as opposed to internal state-sync traffic): zero. Every Received message from webview entry in the log is internal housekeeping the extension sends automatically on window load/resume — get_claude_state, list_sessions_request, rename_tab, update_session_state — not anything a human typed.
  • The hang occurred twice in this window: once ~2-3 minutes after the extension host auto-resumed the dormant session, and again ~6 hours later, with the session sitting completely untouched the entire time in between.

This means the hang is not tied to active use of any particular project, and does not require user interaction to occur at all. It happened twice in a row in an idle, auto-resumed session that nobody was actively working in, in a project unrelated to the one in the original report. Combined with the earlier finding that the last logged action before freezing is the atomic rewrite of the shared, cross-project ~/.claude.json file, this points toward periodic background/idle housekeeping (config cache reload on session resume, feature-flag cache refresh, MCP reconnection, or similar) as the trigger, rather than anything project-specific or usage-pattern-specific.

terrancedjones · 1 month ago

Retracting the EngageHunter attribution — could not verify with confidence

The reporter has firmly and repeatedly stated EngageHunter has never exhibited this hang, in contrast to my last two updates attributing captured hangs to an EngageHunter-Go/React session.

I cannot fully reconcile my log-based evidence with the reporter's direct, first-hand experience, and I was unable to independently verify whether the window in question was actually a visible, user-facing VS Code window (a macOS accessibility permission block prevented checking real window titles, and the process in question had already exited by the time I tried to verify further). No cron job, launchd agent, or scheduled-task configuration was found that would explain an automated/background trigger either, so I don't have a clean alternative explanation — just insufficient confidence to keep standing behind the specific project attribution.

Retracting the "confirmed in a second, unrelated project" framing from my previous two comments. What remains solid, independent of project attribution, from the original reports:

  • The 599-second total log silence with no error before/after
  • VS Code's own unresponsive-extension-host detector never firing
  • The native claude binary consistently idling in a legitimate kevent64 kernel wait during every capture (not a busy-loop), with normal memory footprint
  • The last logged action before at least one freeze was an atomic rewrite of ~/.claude.json, a file shared across all of the reporter's projects
  • At least one occurrence lasted significantly longer (19+ minutes) than the typical ~90-100 second self-resolving pattern seen in earlier captures

Apologies for the churn on this thread — will only report further project-attribution claims once verified with certainty (e.g., confirmed live via the process's parent chain at the moment of capture, not reconstructed afterward).

terrancedjones · 1 month ago

Major update: 4+ days of continuous monitoring — 582 hangs, 39 crash/restart cycles, strong correlation with long-running background subagent calls

The watchdog described in earlier comments has now run continuously since 2026-07-08 without interruption. Aggregate totals:

  • 582 total hang events captured (90+ second silence in the extension's own log while the native process is confirmed alive)
  • 39 distinct window/session identities that hung at least once (each representing a VS Code extension-host crash-and-restart cycle, confirmed via uptime showing zero OS reboots across the entire monitoring window — this is exclusively the Claude Code process itself failing, not the underlying machine)
  • The reporter confirms this pattern has been ongoing for over a month in this specific project, both before and during this monitoring window, and does not occur in their other ~10 actively-used projects on the same machine.

New correlation found today: long-running background subagent (Task-tool) calls

Across a single day of use, every full session crash (not the routine ~90s self-resolving hangs, but the severe ones requiring a fresh window) coincided with a long-running background agent call still in flight or just completed. Concrete examples from today, each followed within minutes by a session crash/restart:

  • Background agent run: 99 tool calls, ~20 minutes wall-clock, ~315k tokens
  • Background agent run: 65 tool calls, ~11.5 minutes wall-clock, ~228k tokens
  • Background agent run: 101 tool calls, ~13 minutes wall-clock, ~518k tokens
  • Background agent run: 35 tool calls, ~17 minutes wall-clock, ~335k tokens

3 separate full-process crashes today, 3 for 3 coinciding with one of these. Each time, the task-notification delivered on the next interaction included the language: "No completion record was found for background agent... It may have been stopped, or it may have been running when the previous Claude Code process exited." — i.e., the extension's own tooling independently corroborates that the parent session died while a long background tool call was outstanding.

This is a testable, specific hypothesis: long-duration / high-tool-call-count background Task/Agent invocations appear to trigger (or strongly correlate with) full extension-host crashes, distinct from the shorter self-resolving kevent64-wait hangs documented earlier in this thread. Given this project's workflow makes heavy, sustained use of long-running background subagents (multi-file codebase audits, spec generation) compared to the reporter's other projects, this plausibly explains why the crash pattern has appeared concentrated in this one project — not because of anything specific to this project's code, but because of how heavily and continuously it's driving long background agent calls.

Impact

Reporter's own words: work and conversational context is not lost (background agent output persists to disk and can be resumed), but each occurrence costs real time (noticing the crash, re-establishing context, resuming background work) and token spend (context has to be rebuilt/re-summarized after each restart). This has been a continuous, multi-week productivity cost, not an occasional annoyance.

Suggested next diagnostic step

Test whether this reproduces on the standalone claude CLI (outside the VS Code extension) under equivalent long-running background-agent load. If it does not reproduce there, that would strongly localize the fault to the extension's handling of long-lived background tool execution specifically (webview/extension-host coordination during long async tool calls), rather than the core agent runtime.

terrancedjones · 1 month ago

New data point: hang-induced VS Code restarts silently kill in-flight background agent tool calls, and mislabel them as user-cancelled

Follow-up to the earlier reports in this thread. Today, two consecutive background Task/Agent tool invocations (each a long-running codebase investigation + spec-writing call, same shape as the ones previously reported to correlate with crashes) were lost when the reporter's Claude Code window became unresponsive and they manually restarted VS Code to recover — the same underlying hang problem already documented above, not a new issue.

What's new: after the restart, checking on either background agent's status returned:

"Agent was stopped by the user and won't be resumed. Treat its work as cancelled; only launch a new agent if the user explicitly asks."

The reporter had not stopped or cancelled anything — they only restarted the VS Code window because it had become unresponsive. The tooling's own status reporting misattributes an extension-crash-induced kill of an in-flight background agent as an intentional user cancellation. This is a secondary, compounding issue on top of the core hang/crash bug: it actively misleads whoever is checking on background work into thinking they (or something they did) caused the loss, when the actual cause is the hang described throughout this thread. No completion record exists for either agent — their work was lost, not just delayed (distinct from the earlier-reported case where background agent output persisted to disk across a crash/resume).

Reporting for completeness — same root cause as the rest of this thread, but the "stopped by the user" mislabeling is itself worth fixing independently of the underlying hang, since it produces an actively incorrect status message regardless of what eventually resolves the core issue.

terrancedjones · 1 month ago

Strong new lead: hang frequency correlates with accumulated session transcript size, not just background-agent load

Follow-up, and a partial correction to the earlier "long background agent" correlation reported above — today's evidence directly contradicted that as a complete explanation (a hang was captured with zero agent activity in the preceding log, plain ordinary chat). Investigating further at the reporter's suggestion (they'd been using one session continuously for 2-3 weeks and started a fresh one to test), a much stronger, quantified correlation emerged:

Comparing the on-disk transcript size (~/.claude/projects/<project>/<session-id>.jsonl) of every session in the affected project:

| Session | Transcript size |
|---|---|
| The session responsible for the large majority of today's verified hangs | 113MB |
| Next-largest session in the same project | 34MB |
| The session used for most of this bug investigation itself | 5.7MB |
| All other sessions in the project | 0.3MB – 21MB |

The hanging session's transcript is more than 3x larger than the next-largest session in the same project, and more than 20x larger than the session most of this investigation was conducted in (which itself has experienced hangs, but far less frequently). The reporter confirms this session had been continuously resumed/used for approximately 2-3 weeks without starting fresh.

This is a plausible, specific mechanism: if session resume or periodic in-session operations require loading, parsing, or holding a growing amount of accumulated transcript history in memory, a session that's grown to 100MB+ over weeks of continuous use would be expected to degrade in exactly this way — more frequent and more severe stalls — compared to a freshly-started session with minimal history. This would also explain why previous attempts to correlate hangs with specific projects, specific background-agent patterns, or specific extensions kept producing partial, inconsistent signals: the actual driver may be cumulative session size/age, which happens to correlate with (but isn't caused by) how heavily and how long any given project's sessions get used.

Suggested engineering angle: check whether session resume, the periodic autocompact-style checks already visible in this extension's own debug log, or any other periodic in-session operation scales with total transcript size in a way that isn't sublinear (e.g., re-reading or re-parsing the full transcript rather than an incremental/paginated approach) as session size grows into the tens-to-hundreds-of-MB range.

terrancedjones · 1 month ago

Correction to the previous comment — the session-size theory doesn't hold up as cleanly as reported

The comparison in the previous comment only measured the main .jsonl transcript file, and made the size disparity look more significant than it actually is. Checking the full accumulated footprint per session (main transcript + separate subagent-transcript storage + tool-result storage, all of which live under the same session directory) tells a different story:

| | Main transcript only | Full accumulated footprint |
|---|---|---|
| The session responsible for most of today's hangs | 113MB | 529MB |
| A comparably long-running session in a different project, reported to never hang | 59MB | 499MB |

529MB vs. 499MB is a ~6% difference — not the 2x+ disparity the narrower comparison suggested. If cumulative session size/age were the real driver, the second session should show similar symptoms, and per the reporter it does not.

Retracting the strength of the size-correlation claim. It's not necessarily wrong that the affected session is old/large (it demonstrably is, in absolute terms), but "size relative to other sessions in the same account" does not appear to be the differentiator once measured fully and fairly. Apologies for the churn — reporting the correction rather than leaving the overstated version standing.

terrancedjones · 1 month ago

Session-size theory definitively ruled out (not just weakened)

Following up on the previous two comments (initial size correlation, then a correction weakening it). Further testing rules it out entirely: the reporter started a fresh session specifically to test this. That new session — confirmed via its own on-disk transcript size, 5.1MB, versus the previous 113MB/529MB session under investigation — has already hung 5 times within approximately 70 minutes of normal use, the same frequency/severity as the large session showed.

A session two orders of magnitude smaller than the one originally suspected is hanging just as often. Session size, age, or accumulated history is not the differentiating factor. Retracting that line of investigation entirely rather than leaving it as a live hypothesis.

Net position after this round of testing: the underlying hang mechanism documented throughout this thread (native process correctly idle in kevent64, ~90-100s self-resolving stalls, occasional more severe multi-minute-to-hours-long stalls, live on extension version 2.1.215 as of this comment) remains fully reproducible and current. Multiple explanations tested and ruled out across this thread: EngageHunter/cross-project attribution (retracted — was a tooling bug in the reporter's own diagnostic script, not evidence of anything), a specific shared config file write, background-agent/Task-tool call duration, and now session size. None of these explain why the reporter's other ~10 actively-used projects on the same machine do not exhibit this pattern while this one project does, consistently, for over a month. That remains unexplained.

terrancedjones · 1 month ago

Update: two more hangs captured today (2026-07-22), one with a new lead

Same watchdog methodology as previous updates (verified attribution via lsof on the exthost log file → pgrep -P for its actual child claude PID(s), not a blanket process-name grep). Both hangs today were the same VS Code window (window17, exthost pid 53680), extension version 2.1.217.

Hang 1 — 09:40:01 EDT, 98s silence
Log context immediately before the stall:

[DEBUG] [API:timing] first byte after 2040ms
Stream started - received first chunk
Received message from webview: {"type":"request",...,"state":"idle",...}
[DEBUG] [skills] idle — switching poll interval to 30000ms

So the assistant response had just started streaming, the webview then reported session state idle, and the extension went silent for 98s right after. vm_stat/swapusage at capture time: 3.87GB/5GB swap used, not memory-pressured — this continues to look unrelated to system memory pressure, more like an internal wait state.

Hang 2 — 09:52:33 EDT, 99s silence — new lead
Log context immediately before the stall:

[DEBUG] Hook output does not start with {, treating as plain text
[INFO] [Stall] tool_dispatch_start tool=Bash toolUseId=toolu_01FVXXgJfhzZdiN79wHh3qWJ permissionDecisionMs=7
[DEBUG] Spawning shell without login (-l flag skipped)

then 99s of silence. This is the first capture where the extension's own internal [Stall] instrumentation appears right before a hang, specifically at tool_dispatch_start for a Bash tool call, immediately followed by shell-spawn. Worth flagging since it's the extension's own telemetry tag, not something I'm inferring — suggests the stall detection is already aware this code path can hang, at least for Bash tool dispatch.

Both hangs self-resolved within the usual ~90-100s window, consistent with every capture so far. Four claude child processes were alive under the same exthost at time of capture (multiple concurrent sessions/subagents in the same window), consistent with earlier notes in this thread — not re-asserting the load-correlation theory I already retracted, just noting it for completeness.

terrancedjones · 1 month ago

Update: caught the exact kevent64 idle-wait signature live, tied to a concrete root cause — orphaned child process after extension-host death

This is a different angle from the previous updates in this thread (which focused on ~90-100s self-resolving stalls detected via log-file silence). This one traces a hang directly to a process-level cause.

What happened: a claude native-binary process (backing a resumed session, extension 2.1.217, macOS ARM64) was still alive and consuming CPU/memory a full 1 hour 33 minutes after I'd last seen it associated with an active VS Code window. Checking its process tree:

PID 80512, PPID 1 (launchd)

Its parent had already died — meaning the VS Code extension host that spawned it (and presumably owned its stdio pipe) had exited or been replaced, but this child process was never cleaned up. It kept running, orphaned, fully detached from any window.

Sampled it for 3 seconds (2501 samples) before killing it:

2501 Thread_16059667  DispatchQueue_1: com.apple.main-thread (serial)
  ...
  2430 kevent64 (in libsystem_kernel.dylib) + 8
  51  (other internal frames, minor activity)

97% of samples (2430/2501) show the main thread parked in kevent64 — precisely the signature in this issue's title ("native process correctly idle in kevent64"). Physical footprint was normal (313MB, peak 323MB) — not a memory-leak/OOM situation, just a process correctly, quietly waiting for an event that can never arrive, because whatever was supposed to deliver it (presumably its original extension host, now dead) is gone.

Why this matters: this gives a plausible concrete mechanism for at least some fraction of the "hangs" reported in this thread — not (only) a transient stall that self-resolves, but the extension host dying/restarting (we've separately confirmed extension hosts do restart/die under normal operation — MCP servers cleanly shutting down, "Closing Claude on channel: ..." log lines, followed by a fresh bootstrap) without properly terminating the claude child process(es) it owned. Those children then persist indefinitely, correctly idle in kevent64, invisible to the user (no window shows them), silently burning CPU/memory, and can never recover because their communication channel is gone. If the original window's webview is still open and waiting on that specific orphaned process for a response, that would present to the user as "this window is still hung" — indefinitely, not just for ~90-100s — since there's no self-resolution path once the parent link is severed.

Killed the process manually (kill <pid>) to reclaim resources; there was no other way to end it.

terrancedjones · 1 month ago

Update: one extension host death takes down multiple unrelated sessions at once; recovery is only partial

This adds an important piece to the orphaned-process finding from my last update (kevent64 idle-wait signature on a process whose parent died).

New observation: two completely unrelated Claude Code sessions — different conversations, different work, one actively mid-task and one much lighter — were both children of the same extension host process. When that extension host died, both sessions were affected simultaneously: their child claude processes were both orphaned (reparented to launchd, ppid=1) at the same moment.

However, recovery was only partial: VS Code appears to have detected the host death and spun up a replacement extension host, which successfully reconnected/resumed the session the user had in the foreground. The other session — which had been running in the background under the same original host — was never reconnected. It was left as a permanent orphan, correctly idle in kevent64 forever, invisible to any window, with no path back.

This matters for root-causing the thread as a whole: it rules out an explanation tied to any individual session's own workload or behavior (the orphaned session in this case was doing comparatively little). The trigger is at the shared extension-host layer, affecting everything hosted under it at once — not something specific to one conversation's tool calls, context size, or activity level. This is consistent with earlier notes in this thread ruling out memory pressure and background-agent-load as primary explanations, and instead points at extension-host lifecycle/crash-recovery as the layer that needs fixing:

  1. Whatever causes the host to die in the first place (still unconfirmed whether this is VS Code platform-level or triggered by extension behavior)
  2. The recovery path only reconnects one session per host death, leaving any others as permanent, unrecoverable zombies with no self-detection or cleanup

Given the earlier tool_dispatch_start tool=Bash correlation (53% of all captured short hangs) and this new "shared host death" pattern, my current best guess at the mechanism: something about spawning shell subprocesses puts enough load/instability on the extension host that it occasionally dies outright rather than just stalling — and whichever sessions happen to be hosted there at that moment go down together, with only the foregrounded one reliably coming back.

Showing cached comments. Read the full discussion on GitHub ↗