Hmbown/CodeWhale · error
LSP request timed out for
Error message
LSP request timed out for {method} What it means
The whole request — send plus reply wait — was wrapped in a tokio timeout with the caller's `wait` budget. This error means the timeout elapsed before the server responded, and it names the method so the caller knows which request starved.
Solutions
- Increase the wait duration for expensive methods or cold-start scenarios
- Wait for server readiness (initialization + first diagnostics) before issuing requests
- Retry the request once — slow-first-request is common while the server warms up
- Check server logs/CPU to distinguish busy-but-alive from hung; restart if hung
Example fix
// before
let reply = client.request("textDocument/completion", params, Duration::from_millis(500)).await;
// after
let reply = client.request("textDocument/completion", params, Duration::from_secs(10)).await; Defensive patterns
Strategy: retry
Validate before calling
// wait for server readiness before expensive first requests client.wait_until_initialized(Duration::from_secs(30)).await?;
Try / catch
match client.request(method, params, wait).await {
Ok(reply) => reply,
Err(e) if e.to_string().starts_with("LSP request timed out for") => {
// one warm-up retry with a longer budget
client.request(method, params, wait * 2).await
}
Err(e) => return Err(e),
} Prevention
- Delay requests until the server signals readiness (initialize reply, first publishDiagnostics)
- Budget generously for cold-start when the server is still indexing
- Classify timeouts: busy-but-alive servers deserve a retry; hung ones need restart
- Track per-method latency to right-size per-method wait budgets
When it happens
Trigger: Language server is slow or busy (indexing, heavy analysis) and replies after the wait budget; server hung or dead so no reply ever arrives; wait duration set too short for an expensive method (e.g. workspace symbol on a huge repo).
Common situations: rust-analyzer/gopls still indexing on first requests; tsserver on a very large project; hover/completion issued immediately after open before the server is ready; deadline tuning too aggressive in tests.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- LSP diagnostics timed out before a current publication
- LSP diagnostics timed out sending document
- LSP diagnostics timed out waiting for another document
- LSP initialized notification timed out
- LSP request channel closed
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8c05a9437ffc4748.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lsp/client.rs:504
})
.await;
self.pending.lock().await.remove(&id);
match response {
Ok(Ok(reply)) => {
if let Some(error) = reply.get("error") {
let message = error
.get("message")
.and_then(Value::as_str)
.unwrap_or("LSP request failed");
return Err(anyhow!("{message}"));
}
reply
.get("result")
.cloned()
.ok_or_else(|| anyhow!("LSP response has no result"))
}
Ok(Err(error)) => Err(error),
Err(_) => Err(anyhow!("LSP request timed out for {method}")),
}
}
async fn shutdown(&self) {
let mut child = self.child.lock().await;
if let Some(mut c) = child.take() {
let _ = c.start_kill();
let _ = c.wait().await;
}
for task in &self.tasks {
task.abort();
}
self.pending.lock().await.clear();
}
}
/// Send a JSON value as one Content-Length-framed JSON-RPC message.
async fn send_message(tx: &mpsc::Sender<Vec<u8>>, value: &Value) -> Result<()> {View on GitHub (pinned to 73e0f67d83)