Hmbown/CodeWhale · error

LSP request timed out for

Error message

LSP request timed out for {method}

What it means

The whole request — send plus reply wait — was wrapped in a tokio timeout with the caller's `wait` budget. This error means the timeout elapsed before the server responded, and it names the method so the caller knows which request starved.

Solutions

  1. Increase the wait duration for expensive methods or cold-start scenarios
  2. Wait for server readiness (initialization + first diagnostics) before issuing requests
  3. Retry the request once — slow-first-request is common while the server warms up
  4. Check server logs/CPU to distinguish busy-but-alive from hung; restart if hung

Example fix

// before
let reply = client.request("textDocument/completion", params, Duration::from_millis(500)).await;
// after
let reply = client.request("textDocument/completion", params, Duration::from_secs(10)).await;
Defensive patterns

Strategy: retry

Validate before calling

// wait for server readiness before expensive first requests
client.wait_until_initialized(Duration::from_secs(30)).await?;

Try / catch

match client.request(method, params, wait).await {
    Ok(reply) => reply,
    Err(e) if e.to_string().starts_with("LSP request timed out for") => {
        // one warm-up retry with a longer budget
        client.request(method, params, wait * 2).await
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Language server is slow or busy (indexing, heavy analysis) and replies after the wait budget; server hung or dead so no reply ever arrives; wait duration set too short for an expensive method (e.g. workspace symbol on a huge repo).

Common situations: rust-analyzer/gopls still indexing on first requests; tsserver on a very large project; hover/completion issued immediately after open before the server is ready; deadline tuning too aggressive in tests.

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/8c05a9437ffc4748. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/lsp/client.rs:504

        })
        .await;
        self.pending.lock().await.remove(&id);
        match response {
            Ok(Ok(reply)) => {
                if let Some(error) = reply.get("error") {
                    let message = error
                        .get("message")
                        .and_then(Value::as_str)
                        .unwrap_or("LSP request failed");
                    return Err(anyhow!("{message}"));
                }
                reply
                    .get("result")
                    .cloned()
                    .ok_or_else(|| anyhow!("LSP response has no result"))
            }
            Ok(Err(error)) => Err(error),
            Err(_) => Err(anyhow!("LSP request timed out for {method}")),
        }
    }

    async fn shutdown(&self) {
        let mut child = self.child.lock().await;
        if let Some(mut c) = child.take() {
            let _ = c.start_kill();
            let _ = c.wait().await;
        }
        for task in &self.tasks {
            task.abort();
        }
        self.pending.lock().await.clear();
    }
}

/// Send a JSON value as one Content-Length-framed JSON-RPC message.
async fn send_message(tx: &mpsc::Sender<Vec<u8>>, value: &Value) -> Result<()> {

View on GitHub (pinned to 73e0f67d83)