Hmbown/CodeWhale · error
LSP diagnostics timed out sending document
Error message
LSP diagnostics timed out sending document
What it means
diagnostics_for sends a didOpen/didChange for the document and waits, under an overall deadline, for the language server to reply with publishDiagnostics. This error means the initial open_or_change send itself could not complete within the caller's deadline (the tokio timeout fired on the send future), so the function aborts instead of publishing stale or no diagnostics.
Solutions
- Increase the deadline passed to diagnostics_for so the send has time to complete
- Check that the language-server process is alive and responsive (logs, is_alive)
- Serialize diagnostics_for calls so one document's backpressure does not starve another's send
- If a server restart is suspected, reinitialize the client and retry
Example fix
// before let diags = client.diagnostics_for(path, text, Duration::from_secs(2)).await; // after let diags = client.diagnostics_for(path, text, Duration::from_secs(10)).await;
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure a non-trivial deadline remains before calling
let deadline = Instant::now() + wait;
if deadline <= Instant::now() { bail!("deadline already expired"); } Try / catch
match client.diagnostics_for(path, text, wait).await {
Ok(d) => d,
Err(e) if e.to_string().contains("timed out sending document") => {
// extend budget / check server liveness, then retry once
retry_with_longer_deadline()
}
Err(e) => return Err(e),
} Prevention
- Pass a deadline generous enough for the send plus a full publishDiagnostics wait
- Keep diagnostics_for calls serialized to avoid outbound backpressure
- Monitor language-server process liveness before waiting
- Log server stderr so a wedged send is diagnosable
When it happens
Trigger: Calling diagnostics_for with a deadline already exhausted or too short; open_or_change blocked because the diagnostics_gate or outbound queue is saturated by earlier documents; LSP server unresponsive so the send future stalls past the deadline.
Common situations: Large monorepos where the server is still indexing and backpressure delays didChange; opening a file right as a deadline-based caller (e.g. a test or UI wait) expires; a hung language-server child process.
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
- first timed-out API attempt should reach the test server
- LSP diagnostics timed out before a current publication
- 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/9b29a32bc83e358c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lsp/client.rs:394
async fn diagnostics_for(
&self,
path: &Path,
text: &str,
wait: Duration,
) -> Result<DiagnosticPublication> {
// One receiver cannot serve concurrent polling safely: serialize the
// open/version/send/wait transaction, including semantic ensure_open.
let deadline = tokio::time::Instant::now() + wait;
let _gate = timeout(wait, self.diagnostics_gate.lock())
.await
.map_err(|_| anyhow!("LSP diagnostics timed out waiting for another document"))?;
let path_buf = path.to_path_buf();
let (_, version) = timeout(
deadline.saturating_duration_since(tokio::time::Instant::now()),
self.open_or_change(path, text),
)
.await
.map_err(|_| anyhow!("LSP diagnostics timed out sending document"))??;
loop {
let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
if remaining.is_zero() {
return Err(anyhow!(
"LSP diagnostics timed out before a current publication"
));
}
let mut rx = self.diagnostics_rx.lock().await;
let (file, published_version, items) = match timeout(remaining, rx.recv()).await {
Ok(Some(item)) => item,
Ok(None) => {
return Err(anyhow!(
"LSP diagnostics channel closed before publishDiagnostics"
));
}
Err(_) => {
return Err(anyhow!(
"LSP diagnostics timed out before a current publication"View on GitHub (pinned to 73e0f67d83)