Skip to content

[BUG] VSCode extension: session switching never spawns a second backend — only the first session after each extension activation works #82197

Description

@jasonChang514

Preflight Checklist

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

What's Wrong?

In the VSCode extension, only the first session opened after each extension-host activation gets a backend process. Every subsequent session switch creates a channel but never spawns a backend, so the session accepts typed input yet never dispatches an API request — the UI spins indefinitely until the user interrupts.

Developer: Reload Window restores exactly one working session; the first switch after it breaks again. Observed across 5/5 reloads in a single day.

What Should Happen?

Expected behavior

Session B spawns its own backend process and responds.

Actual behavior

  • Launching Claude on channel: <id> is logged for session B, but no Spawning Claude with SDK query function line ever follows.
  • The typed message is received (io_message present in the log), but no [API REQUEST] /v1/messages is ever dispatched and no stream starts.
  • On user interrupt: sdk_stream_ended_no_result with had_error: true.
  • Switching back to session A behaves identically. It is not session-specific — it is "the 2nd and any later session within one extension-host lifetime".

Error Messages/Logs

### Evidence
One window's `Claude VSCode.log`, ~5.5 hours:

- `Launching Claude on channel`: **32 occurrences**
- `Spawning Claude with SDK query function`: **7 occurrences**

All 7 spawns are the first launch after an extension activation. 5/5 activations reproduce:

| Extension activation | 1st launch after it | Every later launch (a switch) |
|---|---|---|
| 08:44:13 | 08:45:17 spawn OK | 08:46, 08:50, 09:46 — no spawn |
| 09:48:07 | 09:48:10 spawn OK | 09:49 — no spawn |
| 09:49:48 | 09:50:29 spawn OK | 09:50, 09:52 — no spawn |
| 10:01:12 | 10:01:15 spawn OK | 10:03, 11:39, 11:46, 11:47 — no spawn |
| 13:03:41 | 13:03:46 spawn OK | 13:15, 13:28, 13:43, 13:48, 13:53, 14:17 — no spawn |

<details>
<summary>Representative failing sequence (log excerpt)</summary>


13:03:41  Claude code extension is now active
13:03:45  Launching Claude on channel: 301puww53vd   (resume: session A)
13:03:46  Spawning Claude with SDK query function ... resume: session A   <-- the only spawn
13:15:22  Launching Claude on channel: xnan1efn6kd   (resume: session B)
          (no Spawning line, no [API REQUEST], no stream)
13:15:49  interrupt_claude -> Closing Claude on channel: xnan1efn6kd
13:15:49  sdk_stream_ended_no_result {"had_error":true,"message_count":204}


<details>

Steps to Reproduce

  1. Run Developer: Reload Window.
  2. Open session A from the session list → works normally.
  3. Switch to session B.
  4. Type any short message in session B.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

No response

Claude Code Version

2.1.220

Platform

Other

Operating System

Ubuntu/Debian Linux

Terminal/Shell

VS Code integrated terminal

Additional Information

Additional findings

  1. Switching away never closes the live backend. Channel 301puww53vd (the one that spawned) was logged as Launching but never Closing while the user switched away 6 times. Its OS process stayed alive 74 minutes (parent = code) until killed manually.

  2. Killing the orphaned backend does NOT restore spawning. After SIGTERM, the extension logged Closing Claude on channel: 301puww53vd (14:17:25), but the next launch (14:17:39) still produced no spawn. So this is not merely "the single slot is held by an orphan" — the extension host appears to spawn at most once per lifetime.

  3. Secondary bug — interrupt_claude sent with a requestId in the channelId field. Twice, immediately after an apply_settings (effortLevel) change:

    11:43:59  {"channelId":"4ipw2hb01rd","requestId":"tnp5f8upa",
               "request":{"type":"apply_settings","settings":{"effortLevel":"xhigh"}}}
    11:46:16  {"type":"interrupt_claude","channelId":"tnp5f8upa"}   <-- requestId used as channelId
    11:46:16  [warning] Channel not found: tnp5f8upa
    

    Effectively harmless (the real close went through a separate correct path), but an interrupt signal is silently dropped.

  4. Cosmetic: 26 × Channel not found for logEvent: <channel> — telemetry pings (input_lag_sample, time_to_interactive) arriving before the channel is registered. Dropped metrics only, but they cluster heavily around the failing switches.

Ruled out

  • Session size / context limit — the affected transcript holds ~44k tokens of actual message content, far under the limit. A 12 MB transcript and a 340 KB transcript fail identically.
  • Transcript corruption — 96/96 tool_use/tool_result pairs matched; file ends cleanly on an assistant message.
  • Network / API — no 429, no Overloaded, no context-length error anywhere in the log; api.anthropic.com connect time 6 ms.
  • Machine resources — 16 cores, load average ~6.9, 51 GiB RAM free.
  • Developer: Reload Window — tried 5 times; each reload restores only one working session.

Environment

VSCode extension anthropic.claude-code-2.1.220-linux-x64
Claude Code CLI 2.1.220 (installMethod: native)
VSCode 1.105.1
OS Ubuntu 20.04.3 LTS, kernel 5.15.0-139-generic
Config no MCP servers, no plugins, no hooks, no custom skills/agents

Workaround

Run claude in a terminal instead — the CLI process is independent of the extension's channel/backend management and is unaffected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions