Bug: Claude Code VS Code Extension hangs indefinitely on Remote-SSH — orphaned CLI processes cause lock contention and a broken IPC channel that even the Stop button can't recover from

Status Fixed / completed
Reported on v2.1.263
Maintainer reply None cached
Activity 1 comment · opened Sep 7, 2026 · closed Sep 8, 2026

Bug: Claude Code VS Code Extension hangs indefinitely on Remote-SSH — orphaned CLI processes cause lock contention and a broken IPC channel that even the Stop button can't recover from

Environment

  • Extension version: 2.1.263 (anthropic.claude-code-2.1.263-linux-x64)
  • Setup: VS Code Remote-SSH, connecting to an internally hosted Linux server (extension host runs on the remote server)
  • Model: claude-sonnet-5
  • Firewall/proxy: confirmed clean by internal IT (all relevant domains logged as "Allowed"); curl to api.anthropic.com from the server: DNS 2.4ms / Connect 4.7ms / TLS 56ms / Total 79ms — no network-layer issue
  • claude CLI used directly in the same terminal on the same server: works normally / fast
  • Only the VS Code chat webview is affected
  • Reproduced on two consecutive days, including immediately after a full restart of both the remote server and VS Code (i.e. from a guaranteed-clean state, ruling out leftover local state as the sole cause)

Symptom

The chat UI hangs indefinitely (observed: several hours) after sending a message, with no response and no error shown. The Stop button does not cancel or recover the request. A full window/extension reload is needed; occasionally a full "Kill VS Code Server on Host" is needed to get back to a working state.

Evidence 1 (2026-09-07): two CLI processes spawned for one resumed session

For a single launch_claude request from the webview, the extension spawned two separate claude CLI child processes almost simultaneously:

2026-09-07 11:49:15.738 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: auto, version: 2.1.263, resume: 4e3af24e-1e68-42d3-b368-2c21ca9b2568
2026-09-07 11:49:15.761 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: default, version: 2.1.263, resume: undefined

Both ran full startup in parallel and both hit:

[DEBUG] Lock acquisition took longer than expected - another Claude instance may be running

followed by:

[WARN] claude-vscode notification channel error: Received a response for an unknown message ID: {"jsonrpc":"2.0","result":{},"id":0}; further channel errors are not logged this session

Then the log went silent for 46 seconds (11:49:19.789 → 11:50:05.584) before only a webview input_lag_sample telemetry event (durationMs: 5008) appeared. No timely response reached the webview.

Evidence 2 (2026-09-08): only one process spawned by the extension, but the lock warning still fires — pointing to orphaned processes from earlier hangs

The next day, a brand-new session (not resumed) showed only a single "Spawning Claude" call from the extension:

2026-09-08 11:48:08.782 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: auto, version: 2.1.263, resume: undefined

Yet the spawned process still logged:

2026-09-08T09:48:09.822Z [DEBUG] Lock acquisition took longer than expected - another Claude instance may be running

This strongly suggests a leftover/orphaned claude process from a previous hang was still running and holding the lock on ~/.claude.json, even though the extension itself only launched one process this time. Hung sessions appear to leave zombie processes behind rather than being cleaned up, and those zombies then degrade every subsequent session.

A second request on the same day (resuming session f1375c89-9125-4470-9d29-cd006f71a3d8, after the assistant had shown a waiting_input state for an AskUserQuestion permission prompt) showed a new symptom:

11:48:16.858 [info] Launching Claude on channel: wbq61o6sr2a
11:48:17.052 [warning] Channel not found for logEvent: wbq61o6sr2a

The extension's own channel-tracking failed to find the channel it had created ~200ms earlier. The same "unknown message ID" WARN recurred:

2026-09-08T09:48:20.109Z [WARN] claude-vscode notification channel error: Received a response for an unknown message ID: {"jsonrpc":"2.0","result":{},"id":0}; further channel errors are not logged this session

(Despite the "further channel errors are not logged this session" text, this same warning fires again for every new spawned process — the suppression appears to be scoped per-process, not per extension-host-session, so it doesn't actually indicate a one-time event.)

After this WARN at 11:48:20.112, the debug log stops completely — no further "From claude:" output, no further webview messages — matching the multi-hour hang the user observed. The Stop button produced no effect, consistent with the extension having lost track of which channel/process to signal.

Evidence 3 (2026-09-08, after a full clean restart of both the remote server and VS Code): identical double-spawn recurs — rules out orphaned processes as the sole cause

To rule out leftover processes as the explanation, both the remote server and VS Code were fully restarted. The double-spawn on resume still occurred, from a guaranteed-clean state:

2026-09-08 12:12:39.085 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: auto, version: 2.1.263, resume: f1375c89-9125-4470-9d29-cd006f71a3d8
2026-09-08 12:12:39.118 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: default, version: 2.1.263, resume: undefined

Both processes (PIDs 7721 and 7724) then repeatedly wrote to ~/.claude.json within about 1 second of each other (4 writes total), with "Lock acquisition took longer than expected" logged twice — direct evidence of active file-level contention between the two processes, not stale state from a previous run. There was also an unexplained ~10 second gap between "Launching Claude on channel" (12:12:29.158) and the first "Spawning Claude" log line (12:12:39.085), before any process work began.

This confirms the double-spawn-on-resume is deterministic, reproducible behavior of extension version 2.1.263 itself, not a side effect of accumulated orphaned processes (though orphaned processes from earlier hangs do appear to make things worse on top of this, as in Evidence 2).

Evidence 4 (2026-09-08, extension version 2.1.257): lock contention now produces a hard error, not just a delay

On extension version 2.1.257, the same double-spawn-on-resume pattern occurred again:

2026-09-08 12:34:26.995 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: auto, version: 2.1.257, resume: f1375c89-9125-4470-9d29-cd006f71a3d8
2026-09-08 12:34:27.048 [info] Spawning Claude with SDK query function - cwd: /var/www, permission mode: default, version: 2.1.257, resume: undefined

This time the lock contention escalated to a hard error (not just the usual "took longer than expected" debug line):

2026-09-08T10:34:27.834Z [ERROR] Failed to save config with lock: Error: Lock file is already being held

Notably, this particular request did eventually complete (turn ended normally after ~30 seconds: [engine] turn 1 end (turns=2 usage in=4 out=594 cost=$0.0708 api=8134ms stop=end_turn resultLen=886)), so the double-spawn/lock-contention issue does not always produce a full hang — sometimes it manifests as a large, variable delay (here ~30s for a trivial "ok" prompt) instead, with the multi-hour full hangs in Evidence 1–3 presumably an escalation of the same race under less favorable timing.

Impact

  • Every session resume spawns two full claude CLI processes, which race on ~/.claude.json, causing lock contention (sometimes escalating to an outright "Failed to save config with lock" error) and doubled startup overhead — reproducible from a completely clean state (fresh server reboot + fresh VS Code).
  • Hung sessions additionally appear to leave orphaned claude CLI processes running on the (remote) host, which compounds the lock contention for later sessions on top of the base double-spawn issue.
  • The webview↔extension↔CLI-process notification channel can desync (channel "not found" immediately after creation; responses arriving with an untracked message ID), after which the UI hangs with no recovery path — the Stop button does not work in this state.
  • Once this happens, only a full "Kill VS Code Server on Host" + reconnect (or in this case a full server + VS Code restart) temporarily restores things — and even then, the underlying double-spawn-on-resume still occurs on the very next resumed session.

Suspected root cause areas

  1. The webview→extension launch_claude handler for the resume path spawns a second, unrelated permission mode: default, resume: undefined process alongside the intended resume process, on every resume, unconditionally — not just when something has gone wrong.
  2. Process lifecycle: when a request hangs/errors/is stopped, the underlying claude SDK query child process is not reliably cleaned up, leaving it running and holding ~/.claude.json's lock for future sessions.
  3. Channel/message-ID bookkeeping: the notification channel used for webview↔extension↔CLI-process communication is not reliably scoped/cleaned per spawned process, leading to "unknown message ID" responses and "channel not found" errors, which appear to be the direct cause of the UI hanging with no response and the Stop button not working.

Related upstream reports

At least two prior regressions in Remote environments look related, and neither appears to have been fixed in any version up to the current 2.1.263:

  • #45729 ("Claude Code for VS Code hangs in 2.1.78+"): reports the same "AuthManager initialized" appearing twice at startup (also observed here) in a Remote environment (WSL there, Remote-SSH here). Regression introduced at version 2.1.78; downgrading to 2.1.77 reported to resolve it immediately. Closed as "not planned".
  • #21960 ("VSCode Remote SSH: Extremely slow tool execution / UI unresponsive"): an even closer environmental match — VS Code Remote-SSH specifically, not WSL. Extension shows a working indicator indefinitely, the Stop button doesn't reliably help, responses sometimes only appear after a reload — closely matching the symptoms here. Regression introduced between 2.1.19 and 2.1.20; downgrading to 2.1.19 reported to resolve it completely. Closed as duplicate.

If both regressions are still present and cumulative through to 2.1.263 (which the evidence above suggests, since the current version still exhibits matching symptoms), a downgrade to 2.1.77 would still contain the earlier 2.1.20 regression and might not fully resolve things for a Remote-SSH setup — 2.1.19 may be the more reliable known-good baseline specifically for Remote-SSH, at the cost of losing many releases' worth of other fixes/features.

Additional finding: version downgrades are easy to get wrong on Remote-SSH (separate from the main bug, but worth fixing/documenting)

While trying to downgrade to a known-good version as a workaround, the fix appeared not to take effect: the debug log still showed version: 2.1.257 and a path under .../anthropic.claude-code-2.1.257-linux-x64/... instead of the intended 2.1.77.

Cause: in a Remote-SSH workspace, VS Code's Extensions sidebar lists two separate groups — "Local – Installed" (the extension copy on the client machine) and "SSH: <host> – Installed" (the copy actually installed on the remote host, under ~/.vscode-server/extensions/). Only the version in the "SSH: <host>" group is the one that actually runs and produces the debug log. Using "Install Another Version…" on the entry under "Local" silently has no effect on the running instance — there is no error or warning that the "wrong" copy was changed.

To correctly pin a version on Remote-SSH: open the Extensions view while connected, switch the list to the "SSH: <host>" group specifically, right-click the Claude Code entry there, and choose "Install Another Version…". Afterwards, confirm the change took effect by checking the extension's own debug log for the version: field and the native-binary path, rather than trusting the Extensions panel UI alone.

This is a plausible source of confusion/false negatives for anyone trying to use a version downgrade as a workaround for the hang described in this report (or in #45729 / #21960) on Remote-SSH, since the UI gives no indication that the downgrade target was ambiguous.

Steps to reproduce

  1. Connect VS Code to a remote host via Remote-SSH, open a workspace with an existing/resumable Claude Code session.
  2. Resume the session from the chat panel and send a message.
  3. Observe two "Spawning Claude with SDK query function" log lines close together (one with resume: <sessionId>, one with resume: undefined), followed by "Lock acquisition took longer than expected" and repeated concurrent writes to ~/.claude.json.
  4. Over repeated session launches/resumes across a workday, the notification channel eventually desyncs ("Channel not found for logEvent" shortly after a channel is created, followed by an "unknown message ID" WARN), after which the log goes silent and the UI hangs indefinitely with a non-functional Stop button. This has been observed to persist for hours and to survive a full VS Code reload.

Suggested workaround (until fixed)

  1. Downgrade the extension to version 2.1.77 first — smaller jump, matches the "AuthManager initialized twice" symptom exactly. On Remote-SSH, do this in the Extensions view while connected: switch the list to the "SSH: <host>" group (not "Local"), right-click the Claude Code entry there, choose "Install Another Version…", and pick 2.1.77 — then confirm it actually took effect via the version: field in the extension's own debug log (see "Additional finding" above; installing under "Local" instead silently has no effect on the running instance, which is what happened on the first attempt here — it landed on 2.1.257 and still reproduced the double-spawn). If the hang/slowness persists on a confirmed 2.1.77, fall back further to 2.1.19, which more precisely matches the Remote-SSH environment in #21960. Neither is yet independently confirmed against this exact double-spawn-on-resume symptom, but both are the strongest available leads since no newer, fixed version exists (2.1.263 is current as of 2026-09-06).
  2. Periodically (e.g. daily, via cron on the remote host) run pkill -9 -f "native-binary/claude" to clear orphaned processes, and use VS Code's "Remote-SSH: Kill VS Code Server on Host" + reconnect to reset the extension host's channel state when a hang occurs, rather than relying on Disable/Enable Extension or a simple window reload.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗