Hmbown/CodeWhale · error
LSP semantic request timed out sending document
Error message
LSP semantic request timed out sending document
What it means
After acquiring the gate, request_for_document sends the document via open_or_change under the remaining deadline. This error means the send did not finish before the deadline — the document update itself is stuck (backpressure, dead server, or full queue), so the subsequent LSP method request would operate on stale text and is skipped.
Solutions
- Increase the wait budget, ensuring the send phase has meaningful time left after gate acquisition
- Check the language-server process health and restart it if the outbound queue is not draining
- Reduce concurrent document churn so the outbound channel is not backlogged
- Retry with a fresh deadline
Defensive patterns
Strategy: retry
Validate before calling
// reserve send time: don't call when the deadline is nearly spent
let remaining = deadline.saturating_duration_since(Instant::now());
if remaining < Duration::from_millis(500) { bail!("not enough budget left to send document"); } Try / catch
match client.request_for_document(path, text, method, params, wait).await {
Ok(reply) => reply,
Err(e) if e.to_string().contains("timed out sending document") => {
check_server_alive(&client).await?;
client.request_for_document(path, text, method, params, wait).await
}
Err(e) => return Err(e),
} Prevention
- Give the total wait enough headroom after gate acquisition for the send plus reply
- Watch outbound queue depth; a wedged server never drains didChange
- Restart the language server when sends start timing out repeatedly
- Avoid flooding didChange for many documents at once
When it happens
Trigger: open_or_change blocked behind a full outbound channel while the server is unresponsive; deadline nearly exhausted after a long gate wait so almost no time remains for the send; language-server process hung.
Common situations: Server wedged mid-session so writes never drain; semantic request issued at the tail of a tight deadline after contending on the gate; test harness with very short waits against a slow fake server.
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/8fc5de8b86bd88f3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lsp/client.rs:444
async fn request_for_document(
&self,
path: &Path,
text: &str,
method: &str,
params: Value,
wait: Duration,
) -> Result<SemanticReply> {
let deadline = tokio::time::Instant::now() + wait;
let _gate = timeout(wait, self.diagnostics_gate.lock())
.await
.map_err(|_| anyhow!("LSP semantic request timed out waiting for another document"))?;
let (_, version) = timeout(
deadline.saturating_duration_since(tokio::time::Instant::now()),
self.open_or_change(path, text),
)
.await
.map_err(|_| anyhow!("LSP semantic request timed out sending document"))??;
let result = self
.request(
method,
params,
deadline.saturating_duration_since(tokio::time::Instant::now()),
)
.await?;
Ok(SemanticReply {
result,
document_version: Some(version),
})
}
async fn ensure_open(&self, path: &Path, text: &str) -> Result<()> {
let _gate = self.diagnostics_gate.lock().await;
self.open_or_change(path, text).await?;
Ok(())
}View on GitHub (pinned to 73e0f67d83)