Hmbown/CodeWhale · error
LSP semantic request timed out
Error message
LSP semantic request timed out
What it means
`request_for_document` wraps the semantic request in `tokio::time::timeout`; this error fires when the inner request does not complete within the allotted wait. The reply never arrived in time, so the semantic operation is abandoned.
Solutions
- Increase the wait duration passed to the request
- Check the LSP server is still alive and producing logs
- Retry the request once on timeout before failing the user action
- Verify the request id/response matching works (no dropped responses)
Example fix
// before let wait = Duration::from_millis(500); let reply = request_for_document(transport, path, method, params, wait).await?; // after let wait = Duration::from_secs(10); // semantic replies can be slow let reply = request_for_document(transport, path, method, params, wait).await;
Defensive patterns
Strategy: retry
Validate before calling
// before issuing: ensure server responsive
let ping = tokio::time::timeout(Duration::from_secs(2), transport.request("shutdown", json!({}), Duration::from_secs(1))).await.is_ok(); Try / catch
match request_for_document(...).await {
Err(e) if e.to_string().contains("timed out") => request_for_document(... with 3x wait).await,
other => other,
} Prevention
- Size the wait to the slowest expected server (seconds, not ms)
- Pre-warm the server before user-triggered semantic requests
- Log server stderr to catch hangs early
When it happens
Trigger: LSP server slow or hung answering the request; wait duration too short for large documents or slow servers; transport deadlock so no response is ever produced.
Common situations: Large monorepo files where rust-analyzer/clangd takes seconds to index; server crashed mid-request; wait configured to a few hundred milliseconds.
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 timed out for
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/3e2a0253418b68df.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lsp/client.rs:130
/// Synchronize and query one document atomically when the transport can
/// prove that ordering. Diagnostic-only/legacy transports stay unverified.
async fn request_for_document(
&self,
path: &Path,
text: &str,
method: &str,
params: Value,
wait: Duration,
) -> Result<SemanticReply> {
timeout(wait, async {
self.ensure_open(path, text).await?;
Ok(SemanticReply {
result: self.request(method, params, wait).await?,
document_version: None,
})
})
.await
.map_err(|_| anyhow!("LSP semantic request timed out"))?
}
/// Ensure `path` is open with `text` (didOpen/didChange) so position-based
/// requests can target it. Default is a no-op; real transports track opens.
async fn ensure_open(&self, _path: &Path, _text: &str) -> Result<()> {
Ok(())
}
/// A closed transport is never valid cache evidence. Diagnostic-only
/// in-process implementations remain usable until their owner removes them.
fn is_alive(&self) -> bool {
true
}
/// Best-effort shutdown. Called via `LspManager::shutdown_all`.
async fn shutdown(&self);
}
View on GitHub (pinned to 73e0f67d83)