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

  1. Increase the wait deadline to cover the server's diagnostic debounce latency
  2. Verify the server actually sends publishDiagnostics for didChange (check capability / server logs)
  3. Retry once with a fresh deadline; a transient slow publish resolves on retry
  4. 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

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.

Related errors


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)