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

  1. Increase the wait duration so it covers the gate holder's worst-case hold time
  2. Shorten or chunk diagnostics_for's gate hold (publish outside the gate) to reduce contention
  3. Queue semantic requests behind a single in-flight request instead of many concurrent waits
  4. 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

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.

Related errors


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)