Skip to content

vscode-languageclient v10 breaks restartServer: client never returns to Running #195

Description

@MelbourneDeveloper

Summary

Upgrading vscode-languageclient from ^9.0.1 to ^10.1.0 makes sharplsp.restartServer fail to bring the client back up. Two lifecycle-e2e tests fail reproducibly on Windows, and the chunk's runtime jumps from ~20s to ~2m (the added time is the assertions timing out).

The upgrade was attempted alongside the VS Code SDK bump (engines.vscode / @types/vscode ^1.99.0^1.125.0). The SDK bump is fine and has shipped; only the vscode-languageclient major was reverted to ^9.0.1, so this is tracked here rather than lost.

Failing tests

Both in editors/vscode/src/test/suite/lifecycle-e2e.test.ts (Windows chunk lifecycle):

  • restartServer recovers the live client and keeps it serving symbolsAssertionError: Server must serve symbols again after restart (actual false, expected true)
  • restartServer drives the live status bar through Starting and back to RunningAssertionError: Server (and status bar) recovered to Running

Evidence — controlled A/B on the same machine, same commit

Only editors/vscode/{package.json,package-lock.json,src/client.ts,src/output-filter.ts,src/test/suite/fsi-build-output-e2e.test.ts} differed between runs; everything else (Rust host, both sidecars, fixtures) was byte-identical.

Dependency state Result Wall time
vscode-languageclient@10.1.0 60 passing, 2 failing 2m
vscode-languageclient@9.0.1 62 passing, 0 failing 20s

Reproduce with make _test-vsix-win CHUNK=lifecycle.

Notes for whoever picks this up

  • v10 adds a State.StartFailed enum member, splitting a failed launch out of State.Stopped. wireStatusBar in editors/vscode/src/client.ts must handle it (as ServerState.Error) or switch-exhaustiveness-check fails lint. The StartFailed handling is not itself the cause of the restart failure — the restart path never reaches Running at all — but it is required for the upgrade to compile and lint.
  • v10 retypes LanguageClientOptions.outputChannel from OutputChannel to LogOutputChannel. That migration is already done and shipped: createAnsiStrippingChannel returns a LogOutputChannel and strips ANSI from the five level-tagged log methods. LogOutputChannel extends OutputChannel, so it remains assignable on v9 — no work needed here on re-attempt.
  • The likely area is client.restart() / stop-then-start sequencing changing in v10, so the status-bar state machine and the "serving symbols again" probe both time out. Worth checking whether restart() now resolves before the server is actually ready.

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