Detail Bug Report
https://app.detail.dev/org_4c5b920c-9e04-4530-a4d2-953927859978/bugs/bug_46551983-d830-4599-aeef-326f361075a3
Summary
- Context: The
typos.restart command in the VSCode extension stops and restarts the language server client when configuration changes or when explicitly invoked by the user.
- Bug: The restart command uses
client.needsStop() to check if the client should be stopped before calling client.stop(), but needsStop() returns true for both Starting and Running states, while stop() only accepts the Running state.
- Actual vs. expected: When the client is in the
Starting state, needsStop() returns true but stop() throws an error "Client is not running and can't be stopped", causing the restart to fail. The expected behavior is that the restart should either wait for the client to finish starting or handle the Starting state gracefully.
- Impact: If a user triggers multiple rapid configuration changes or manually executes the restart command while the language server is still starting, the extension will crash or show an error message, disrupting the user's workflow.
Code with bug
vscode.commands.registerCommand("typos.restart", async () => {
// can't stop if the client has previously failed to start
if (client && client.needsStop()) { // <-- BUG 🔴 needsStop() true for Starting; stop() then throws
await client.stop();
}
Codebase inconsistency
- From vscode-languageclient:
needsStop() {
return this.$state === ClientState.Starting || this.$state === ClientState.Running;
}
// We can't stop a client that is not running (e.g. has no connection). Especially not
// on that us starting since it can't be correctly synchronized.
if (connection === undefined || this.$state !== ClientState.Running) {
throw new Error(`Client is not running and can't be stopped. It's current state is: ${this.$state}`);
}
- Conclusion:
needsStop() returns true for Starting, but stop() throws unless state is Running. Using needsStop() to gate stop() causes an error when the client is starting.
Recommended fix
Only stop when the client is actually running:
vscode.commands.registerCommand("typos.restart", async () => {
// Only stop if the client is running
if (client && client.state === State.Running) { // <-- FIX 🟢 restrict stop() to Running state
await client.stop();
}
// ...recreate and start client
});
And ensure State is imported:
import { State } from "vscode-languageclient/node";
Detail Bug Report
https://app.detail.dev/org_4c5b920c-9e04-4530-a4d2-953927859978/bugs/bug_46551983-d830-4599-aeef-326f361075a3
Summary
typos.restartcommand in the VSCode extension stops and restarts the language server client when configuration changes or when explicitly invoked by the user.client.needsStop()to check if the client should be stopped before callingclient.stop(), butneedsStop()returnstruefor bothStartingandRunningstates, whilestop()only accepts theRunningstate.Startingstate,needsStop()returnstruebutstop()throws an error "Client is not running and can't be stopped", causing the restart to fail. The expected behavior is that the restart should either wait for the client to finish starting or handle theStartingstate gracefully.Code with bug
Codebase inconsistency
needsStop()returnstrueforStarting, butstop()throws unless state isRunning. UsingneedsStop()to gatestop()causes an error when the client is starting.Recommended fix
Only stop when the client is actually running:
And ensure
Stateis imported: