neoclide/coc.nvim · error · Error
Stopping the server timed out
Error message
Stopping the server timed out
What it means
BaseLanguageClient.stop() waits for the server connection to end within a timeout window. If the connection has not been ended when the timeout fires, the client logs 'Stopping server timed out' and throws so callers know shutdown did not complete cleanly. The state is still forced to Stopped in the finally block.
Source
Thrown at src/language-client/client.ts:1381
})(connection)
// If the connection closes while the shutdown is in flight (e.g. the
// server crashed), handleConnectionClosed signals it here so the stop
// completes successfully: the server is gone, which is the outcome the
// caller asked for. Without this, the pending shutdown rejects after the
// connection is disposed, reporting a false stop failure.
const close = new Promise<Connection>(resolve => {
this._onStopClose = () => resolve(connection)
})
return this._onStop = Promise.race([tp, shutdown, close]).then(connection => {
if (tm) clearTimeout(tm)
// The connection won the race with the timeout.
if (connection !== undefined) {
connection.end()
connection.dispose()
} else {
this.error(`Stopping server timed out`, undefined)
throw new Error(`Stopping the server timed out`)
}
}, error => {
this.error(`Stopping server failed`, error)
throw error
}).finally(() => {
this.$state = ClientState.Stopped
if (mode === 'stop') {
this.cleanUpChannel()
}
this._onStart = undefined
this._onStop = undefined
this._onStopClose = undefined
this._connection = undefined
this._ignoredRegistrations.clear()
})
}
public dispose(timeout = 2000): Promise<void> {View on GitHub (pinned to 50e974d969)
Solutions
- Check the server implementation responds to the shutdown/exit requests promptly
- Increase the shutdown timeout passed to the client constructor options
- Kill leftover server processes manually and retry stopping
- Update or replace the misbehaving language server
Example fix
// before
await client.stop()
// after
try {
await client.stop()
} catch (e) {
// server ignored shutdown; state is already Stopped
console.warn('Server did not shut down cleanly:', e)
} Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-call validation; ensure server supports shutdown before stop // e.g. check capabilities negotiated during initialize contain shutdown support
Try / catch
try {
await client.stop()
} catch (e) {
if (String(e.message).includes('Stopping the server timed out')) {
// force-kill leftover server process; client state is already Stopped
} else { throw e }
} Prevention
- Choose language servers that implement shutdown/exit correctly
- Set an adequate shutdown timeout in client options
- Avoid calling stop() while long requests are in flight
- Monitor for orphaned server processes after deactivation
When it happens
Trigger: Calling client.stop() (or extension deactivate) while the language server process hangs, ignores the shutdown request, or takes longer than the shutdown timeout (default 1s, configurable via a requestTimeout/shutdown timeout option).
Common situations: A server that never responds to the LSP 'shutdown' request, a server blocked on I/O or a deadlock, slow teardown on Windows where process kill is asynchronous, or an extension deactivating while a request is still in flight.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Required root pattern not resolved.
- keymap: "${name}" already exists.
- Extension ${id} not registered!
- Extension ${id} not registered
- Client got disposed and can't be restarted.
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/92b4c49c10a42c91.
Report an issue: GitHub.