[BUG] IDE connection never reconnects after the VS Code extension host restarts (no retry on transport close)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
When the VS Code extension host restarts, every running claude session in that window loses its IDE connection and never gets it back. The session stays "IDE disconnected" for the rest of its life unless the user manually runs /ide (and users commonly just restart the terminal instead, losing the session).
The CLI has no retry on IDE transport close. IDE discovery is only ever kicked off at session start.
This is the underlying mechanism behind the long tail of "IDE disconnected" reports (#26285, #4837, #4871, #14116, #16394), most of which were closed by the stale bot rather than fixed. Unlike those, this issue names the specific missing code path.
What Should Happen?
When the IDE MCP transport closes, the CLI should re-run IDE discovery with backoff and reconnect automatically — the same way it discovers the IDE at session start. The user should not have to run /ide or restart the terminal.
Root cause (traced in the 2.1.245 CLI bundle and the 2.1.245 extension)
1. The extension tears the server down on dispose — deleting its lock file and closing the WebSocket server, so every connected CLI session's socket closes:
dispose: async () => {
if (x !== null) aT0(x) // delete ~/.claude/ide/<port>.lock
...
K.close() // close the WS server -> all CLI clients drop
}
This runs on any extension host restart: window reload, ext host crash, or any extension install/update — including the CLI's own code --force --install-extension anthropic.claude-code, which it issues whenever the installed extension version differs from the CLI version. Since the CLI and extension are released in lockstep and the CLI auto-updates, launching claude in one terminal routinely restarts the extension host and drops every other live Claude session in that window.
2. The CLI never retries. The discovery routine (a 30-second poll loop) has exactly two call sites in the whole bundle, both inside the session-start hook:
async function lNa(e, t, n, r, o, s) {
I$n().then(e); // <- at session start
...
OUo(a, s).catch(...).then((c) => {
if (c?.installed && !o?.aborted) I$n().then(e) // <- after installing the extension
})
}
Nothing is wired to transport close. Protocol._onclose() clears handlers and rejects pending requests; there is no rediscovery, no reconnect, no backoff for ws-ide / sse-ide transports.
3. Reconnecting manually is on the slow path. On restart the extension binds a new random port (Math.floor(Math.random()*55536)+1e4) and republishes it via environmentVariableCollection.replace(), which only reaches newly created terminals. The live session's CLAUDE_CODE_SSE_PORT now points at a dead port, so /ide falls off the exact-port match onto the stricter PID-ancestor path:
if (a) { // running in a VS Code terminal
if (!(n !== null && l.port === n)) { // env port doesn't match this lock
if (!l.pid || !j$n(l.pid)) continue;
if (process.ppid !== l.pid && !(await i()).has(l.pid)) continue; // silently skipped
}
}
That path works on macOS but is exactly what fails in #42141 on Windows — and it is why "restart the terminal" is the folk remedy: a fresh terminal picks up the new port and matches exactly.
Steps to Reproduce
- Open VS Code with the Claude Code extension, start
claudein the integrated terminal, confirm/ideshows connected. - Restart the extension host —
Developer: Restart Extension Host, a window reload, or install/update any extension. - The running session shows "IDE disconnected".
- Wait indefinitely: it never reconnects.
~/.claude/ide/<old-port>.lockis gone and a new lock with a different port exists. - Only
/ide(or a new terminal) restores it.
Error Messages/Logs
Extension log (Claude VSCode.log), one window, two activations ~3.5 min apart, different ports each time:
2026-08-25 16:35:41.756 [info] MCP Server running on port 11306 (localhost only)
2026-08-25 16:39:09.442 [info] MCP Server running on port 21341 (localhost only)
VS Code main.log for the same moment:
2026-08-25 16:39:06.590 [info] Extension host with pid 39747 exited with code: 0, signal: unknown.
2026-08-25 16:39:07.024 [info] Started local extension host with pid 44231.
The session that was connected to 11306 never recovered.
Suggested fixes
- Reconnect on close (the real fix). Hook the
ws-ide/sse-idetransport'soncloseto re-run discovery with exponential backoff, capped. The discovery routine already exists and already polls for 30s. - Ignore a dead
CLAUDE_CODE_SSE_PORT. If the env port isn't connectable, treat it as unset rather than routing detection onto the stricter PID-ancestor path (also suggested in #42141). - Stop re-randomizing the port. Persist the last port in extension state and try to rebind it first, so an ext host restart usually keeps the env var valid.
- Set
environmentVariableCollection.persistent = false. The extension activates ononStartupFinished, i.e. after restored terminals spawn — so with the defaultpersistent: true, terminals restored on a window reload receive the previous session's port before the extension picks a new one. - Don't force-reinstall the extension from the CLI while sessions are live, or at minimum defer it — today a single
claudelaunch can drop every other session in the window.
Claude Code Version
2.1.245 (CLI), 2.1.245 extension, VS Code 1.134.0, macOS (darwin arm64)
Is this a regression?
Not a regression — the reconnect path appears never to have existed.