[BUG] /ide does not keep the connection: a session started with --ide re-takes the single IDE slot within milliseconds
Summary
An explicit /ide connect does not hold if another session in the same VS Code window was started with --ide. The /ide command prints "Connected to Visual Studio Code.", but the other session takes the single IDE slot back within 5–17 ms. The session where I ran /ide ends up with no IDE features and gets no message about it. Turning auto-connect off does not help.
This is related to #87130 (more than one IDE session per window, closed as not planned), but it asks for something smaller. Keep the one-slot design. Let the slot go to the session where I explicitly ran /ide, and stop other sessions from taking it back.
Environment
- Linux host, VS Code 1.139.1 (commit
04c0d99f), workspace opened in a Dev Container (Remote - Containers). - Container run with
--net=host --pid=host --ipc=host. - Claude Code CLI 2.1.291 / 2.1.292, run inside the container.
- VS Code extension
anthropic.claude-code: the running extension host loaded 2.1.288. 2.1.291 is installed, but the window has not been reloaded since. - Several Claude Code sessions run in the same container:
- one interactive session started as
claude --ide --agent <name>in a VS Code integrated terminal; - background sessions hosted by
claude daemon/claude agents.
What happens
- Session A is started in the integrated terminal as
claude --ide …. It connects to the extension's WebSocket server (lock file~/.claude/ide/<port>.lock). - Session B is a background session. I run
/idein it, and it prints "Connected to Visual Studio Code." - The extension evicts A and accepts B. A reconnects within a few milliseconds and evicts B.
- B has no IDE connection: no diagnostics, no selection context, no diff view. B shows nothing about it.
- Turning off auto-connect in
/configchanges nothing. A was already running and was started with--ide. - The only fix was to kill session A. After that, no client held the port, and
/idein B could keep the connection.
Evidence
Extension log: ~/.vscode-server/data/logs/<session>/exthost1/Anthropic.claude-code/Claude VSCode.log.
Every /ide connect from session B logged a pair of connections a few milliseconds apart:
07:27:25.855 [info] New WS connection from: / <- B connects
07:27:25.856 [info] Disconnecting previous WebSocket client <- A evicted
07:27:25.856 [info] MCP server connected to transport
07:27:25.859 [info] WS client disconnected
07:27:25.860 [info] New WS connection from: / <- A reconnects
07:27:25.860 [info] Disconnecting previous WebSocket client <- B evicted
07:27:25.860 [info] MCP server connected to transport
07:27:25.868 [info] WS client disconnected
The same pattern appears at 07:26:41, 07:26:51 and 07:33:03–05. Right after each /ide, /proc/net/tcp showed exactly one connection to the extension's port. Mapping its socket inode to a process gave session A (claude --ide …), never session B.
Observed behavior, by session type:
- A session started with
--idereconnects at once when it is evicted. - This is probably the IDE auto-reconnect path.
- A background session that is evicted does not reconnect.
- So whichever session reconnects automatically wins, even against an explicit user command.
Expected behavior
/ide connects the current session, no matter what else is running:
- An explicit
/ide(or picking the IDE in the/idepicker) gives the slot to the current session. - The session that loses the slot gets a visible notice, e.g. "IDE connection taken over by another Claude Code session".
- After that, the losing session must not reconnect automatically. That includes
--ideand auto-connect sessions. - It reconnects only when the user runs
/idethere again. - Auto-reconnect is still useful when the connection is lost for other reasons, such as an extension restart or a window reload.
- It should not fire when another client took the slot.
- The extension could send a close code or reason like "superseded" so the CLI can tell the two cases apart.
- Nice to have: the
/idepicker shows which session holds the slot now (pid, cwd or session name). Today, finding the holder took/procsocket forensics.
Workaround
Find and stop every session that was started with --ide, then run /ide in the session you want. In a container with --pid=host, this meant mapping the socket's inode from /proc/net/tcp to its pid.