Kuberwastaken/claurst · error · anyhow::Error

LSP error from

Error message

LSP error from {}: {}

What it means

Thrown in `LspClient::send_request_inner` when the JSON-RPC response from the language server contains an `error` member. This is the server's own JSON-RPC error object (code + message) surfaced verbatim to the caller. The request reached the server and was understood, but the server rejected it.

Solutions

  1. Read the embedded JSON-RPC `error` object in the message to identify the server-side code and message.
  2. Ensure `initialize(root_uri)` completed successfully before issuing feature requests.
  3. Check the server's declared capabilities and avoid calling unsupported methods (e.g. hover on a server without hoverProvider).
  4. Fix the request params (position, uri) or the server's initializationOptions in settings.

Example fix

// before: assuming any server supports hover
let hover = manager.hover(path, root, line, col).await?;
// after: degrade gracefully when server reports a JSON-RPC error
let hover = manager.hover(path, root, line, col).await
    .unwrap_or_else(|e| { tracing::warn!("hover unavailable: {e}"); None });
Defensive patterns

Strategy: try-catch

Validate before calling

// Only call methods the server advertises (after initialize, inspect result.capabilities)
let caps = initialize_response["result"]["capabilities"].clone();
let supports_hover = caps.get("hoverProvider").and_then(|v| v.as_bool()).unwrap_or(false);

Try / catch

let result = manager.hover(path, root, line, col).await
    .map_err(|e| { tracing::debug!("LSP server rejected request: {e}"); e })
    .unwrap_or(None); // degrade to no-hover instead of failing the session

Prevention

When it happens

Trigger: Any request via send_request_inner (initialize, hover, definition, references, document_symbols, shutdown) where the server replies with a JSON-RPC error — e.g. method not supported (code -32601), invalid params, or request before initialize.

Common situations: Hover/definition requested on a server that lacks the capability; position out of range for some strict servers; request sent before the `initialize` handshake completed; server's initializationOptions malformed so it rejects requests.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/173a894b80cd363b. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/core/src/lsp.rs:333

            tokio::time::timeout(std::time::Duration::from_secs(30), rx)
                .await
                .map_err(|_| {
                    anyhow::anyhow!(
                        "LSP request '{}' timed out (server: {})",
                        method,
                        self.server_name
                    )
                })?
                .map_err(|_| {
                    anyhow::anyhow!(
                        "LSP request '{}' channel closed (server: {})",
                        method,
                        self.server_name
                    )
                })?;

        if let Some(err) = response.get("error") {
            return Err(anyhow::anyhow!(
                "LSP error from {}: {}",
                self.server_name,
                err
            ));
        }
        Ok(response["result"].clone())
    }

    /// Send a JSON-RPC notification (fire-and-forget, no response expected).
    async fn send_notification_inner(
        &self,
        method: &str,
        params: serde_json::Value,
    ) -> anyhow::Result<()> {
        let msg = json!({
            "jsonrpc": "2.0",
            "method": method,
            "params": params,

View on GitHub (pinned to b0637c97ec)