Skip to content

Claude Code 2.1.207 LSP client wedges permanently when a fallback .venv exists at startup ("server is starting" never clears) #140

Description

@K-dash

Summary

On Claude Code 2.1.207, any session whose LSP proxy starts with a fallback .venv present (the standard single-repo layout: .venv at the project root) loses LSP for the entire session:

  • the first LSP tool call hangs forever and cannot be interrupted with Esc,
  • every subsequent LSP call fails instantly with Cannot send notification to LSP server 'plugin:typemux-cc:typemux-cc': server is starting.

The proxy is not at fault: trace logs show it answered initialize 141–550 ms after receiving it, and the client then never sent another byte — not even initialized. Reproduced 3/3. The venv-less startup path (instant {"capabilities": {}} response) is unaffected (2/2), including full mid-session backend creation afterwards.

The root cause sits in Claude Code's LSP client (its state machine never leaves "starting"), but typemux-cc needs a mitigation because the affected path is the most common deployment shape.

Timeline evidence (proxy trace log, UTC)

Three wedged runs, all on the same path: fallback venv found → backend pre-spawn → handshake → full pyright capabilities returned.

run initialize received response written client traffic afterwards
1 00:36:26.904 00:36:27.427 (523 ms) none (observed >5 min)
2 00:53:51.004 00:53:51.553 (549 ms) none
3 01:05:49.122 01:05:49.263 (141 ms) none; user retries error client-side, nothing reaches the proxy

The response write is proven complete in each run: dispatch_initialize awaits the response write before emitting the Initial backend inserted into pool INFO line, which is present in all three runs, and the subsequent notification forwards succeeded on the same writer.

In each wedged run the proxy also forwarded 6 window/logMessage notifications from pyright ~84–94 ms after the response, i.e. before the client had sent initialized.

Healthy contrast runs (no fallback venv at startup → No fallback backend: returning minimal initialize response, <1 ms):

  • the client proceeded immediately (didOpen arrived 0.7 ms after the response) and all five verified operations (hover, documentSymbol, cross-file definition, references, publishDiagnostics) worked, including a mid-session uv venv with backend creation — the first hover was answered in 667 ms including spawn + handshake + document restoration (see Verify client behavior with frozen empty capabilities when starting without a fallback venv #105 verification),
  • a monorepo session switching across four sub-project venvs was fully functional.

Server-side health was double-checked during a hang: proxy + pyright processes alive and idle, and a scripted stdio client replaying the identical flow (initialize → initialized → didOpen → hover) against the same 0.2.17 binary received the hover answer in 0.46 s.

Trigger hypotheses (not yet discriminated)

All three differ between the wedge path and the healthy path:

  1. the early window/logMessage notifications delivered while the client is still in its "starting" state,
  2. something in pyright's full capabilities payload (the healthy path returns {}),
  3. a race with initialize responses slower than ~100 ms.

Mitigation candidates

  1. Answer initialize immediately with static capabilities and complete the backend handshake asynchronously. This is also the fix candidate already discussed in Verify client behavior with frozen empty capabilities when starting without a fallback venv #105; it structurally dodges hypotheses 1 and 3 and empirically tests 2.
  2. Hold backend→client notifications until the client's initialized arrives. A single-variable test for hypothesis 1, and arguably safer sequencing in general.

Environment

  • Claude Code 2.1.207 (released 2026-07-10; the last-known-good client version is unknown — long-lived sessions started on older versions are unaffected)
  • typemux-cc 0.2.17, pyright 1.1.411 (pip package), macOS (darwin 25.5)

An upstream report to anthropics/claude-code is drafted separately; this issue tracks the typemux-cc-side mitigation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions