Hmbown/CodeWhale · error
LSP semantic request timed out waiting for another document
Error message
LSP semantic request timed out waiting for another document
What it means
request_for_document acquires the shared diagnostics_gate before touching the document, so semantic requests don't interleave with diagnostics publication. This error means it could not acquire that mutex within the wait budget — another task (typically diagnostics_for) held the gate for the entire window.
Solutions
- Increase the wait duration so it covers the gate holder's worst-case hold time
- Shorten or chunk diagnostics_for's gate hold (publish outside the gate) to reduce contention
- Queue semantic requests behind a single in-flight request instead of many concurrent waits
- Retry the semantic request; contention is often transient
Example fix
// before let reply = client.request_for_document(path, text, method, params, Duration::from_secs(1)).await; // after let reply = client.request_for_document(path, text, method, params, Duration::from_secs(15)).await;
Defensive patterns
Strategy: try-catch
Validate before calling
// don't enter with a wait smaller than a typical gate hold
if wait < Duration::from_secs(1) { bail!("wait too small to acquire diagnostics_gate"); } 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 waiting for another document") => {
// gate held by diagnostics; back off and retry
tokio::time::sleep(Duration::from_millis(250)).await;
client.request_for_document(path, text, method, params, wait).await
}
Err(e) => return Err(e),
} Prevention
- Pass a wait budget longer than diagnostics_for's maximum hold time
- Limit concurrent semantic requests during diagnostics publication
- Consider retrying with backoff — gate contention is usually transient
- Keep diagnostics publication latency low so the gate frees quickly
When it happens
Trigger: A long-running diagnostics_for holds diagnostics_gate while waiting up to its full deadline for publications; multiple semantic requests queue behind the gate and later ones expire; caller passes a wait shorter than the gate holder's deadline.
Common situations: Hover/completion issued while a diagnostics publication is still pending; one large document monopolizing the gate during indexing; UI callers with short timeouts contending with background diagnostics.
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/483f0793b59cbc9b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lsp/client.rs:438
items,
document_version: Some(version),
diagnostic_version: published_version,
});
}
}
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),
})
}View on GitHub (pinned to 73e0f67d83)