Hmbown/CodeWhale · error
LSP diagnostics timed out before a current publication
Error message
LSP diagnostics timed out before a current publication
What it means
After successfully sending the document, diagnostics_for loops on the diagnostics broadcast channel waiting for a publishDiagnostics notification matching this file and version. This error is returned when the overall deadline expires before any current (matching) publication arrives.
Solutions
- Increase the wait deadline to cover the server's diagnostic debounce latency
- Verify the server actually sends publishDiagnostics for didChange (check capability / server logs)
- Retry once with a fresh deadline; a transient slow publish resolves on retry
- If the file/version never matches, check that text sent matches the on-disk path version tracking
Defensive patterns
Strategy: retry
Validate before calling
// confirm the server advertises diagnostics support before waiting
let caps = client.capabilities();
if caps.text_document_sync.is_none() { bail!("server will not publish diagnostics"); } Try / catch
match client.diagnostics_for(path, text, wait).await {
Ok(d) => d,
Err(e) if e.to_string().contains("timed out before a current publication") => {
client.diagnostics_for(path, text, wait * 2).await.unwrap_or_default()
}
Err(e) => return Err(e),
} Prevention
- Size the wait to the server's known diagnostic debounce latency
- Avoid re-sending didChange while waiting, or the awaited version never matches
- Confirm server capabilities include full/didChange diagnostics sync
- Use server readiness signals before issuing diagnostics waits
When it happens
Trigger: The server acknowledges the document change but never publishes diagnostics (or publishes only for an older version) before the deadline; the loop discards stale publications (wrong file/version) until time runs out.
Common situations: Servers that debounce or debounce-heavy diagnostics (rust-analyzer, tsserver) take longer than the caller's wait; server publishes diagnostics only after full analysis of a huge file; caller set a tight timeout.
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 sending document
- LSP diagnostics timed out waiting for another document
- LSP initialized notification timed out
- LSP request timed out for
- LSP semantic request timed out
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/564daf5f5301e6f6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lsp/client.rs:398
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"
));
}
};
if file != path_buf || published_version.is_some_and(|published| published != version) {View on GitHub (pinned to 73e0f67d83)