charmbracelet/crush · error
failed to get LSP diagnostics: %w
Error message
failed to get LSP diagnostics: %w
What it means
Client.GetLSPDiagnostics issues GET /workspaces/{id}/lsps/{lspName}/diagnostics and wraps any transport-level failure from the HTTP helper (c.get) with this message. It means the request to the crush server never produced an HTTP response (connection failure, bad URL, canceled context, etc.), not that diagnostics are missing. The underlying cause is always available in the wrapped %w error.
Source
Thrown at internal/client/proto.go:284
}
func sendEvent(ctx context.Context, evc chan any, ev any) bool {
if ctx.Err() != nil {
return false
}
select {
case evc <- ev:
return true
case <-ctx.Done():
return false
}
}
// GetLSPDiagnostics retrieves LSP diagnostics for a specific LSP client.
func (c *Client) GetLSPDiagnostics(ctx context.Context, id string, lspName string) (map[protocol.DocumentURI][]protocol.Diagnostic, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/lsps/%s/diagnostics", id, lspName), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get LSP diagnostics: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get LSP diagnostics: status code %d", rsp.StatusCode)
}
var diagnostics map[protocol.DocumentURI][]protocol.Diagnostic
if err := json.NewDecoder(rsp.Body).Decode(&diagnostics); err != nil {
return nil, fmt.Errorf("failed to decode LSP diagnostics: %w", err)
}
return diagnostics, nil
}
// GetLSPs retrieves the LSP client states for a workspace.
func (c *Client) GetLSPs(ctx context.Context, id string) (map[string]proto.LSPClientInfo, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/lsps", id), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get LSPs: %w", err)
}View on GitHub (pinned to 7944b8e522)
Solutions
- Check the wrapped cause in errors.Unwrap / %v output and fix the underlying transport issue (server down, wrong address).
- Verify the crush server/daemon is running and reachable at the configured base URL.
- Confirm the workspace id and lspName used in the URL path are correct.
- Ensure ctx isn't already canceled/expired before the call; increase timeouts if requests are being dropped.
Example fix
// before
if !isServerRunning() { /* proceed anyway */ }
diags, err := client.GetLSPDiagnostics(ctx, wsID, "gopls")
// after
if !isServerRunning() { return nil, fmt.Errorf("crush server not running at %s", baseURL) }
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
diags, err := client.GetLSPDiagnostics(ctx, wsID, "gopls")
if err != nil { return nil, fmt.Errorf("GetLSPDiagnostics: %w", err) } Defensive patterns
Strategy: try-catch
Validate before calling
if !serverReachable(baseURL) { return fmt.Errorf("crush server unreachable at %s", baseURL) }
if wsID == "" || lspName == "" { return errors.New("workspace id and lsp name are required") } Type guard
func isTransportErr(err error) bool {
var ne net.Error
return err != nil && (errors.As(err, &ne) || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded))
} Try / catch
diags, err := client.GetLSPDiagnostics(ctx, wsID, lspName)
if err != nil {
if isTransportErr(err) {
// server down / network issue — surface or retry with backoff
return nil, fmt.Errorf("LSP diagnostics unavailable: %w", err)
}
return nil, err
} Prevention
- Health-check the server before making dependent calls.
- Always pass a context with an explicit timeout.
- Log the wrapped cause with %v, not just the top-level message.
- Validate workspace id and LSP name before building the request.
When it happens
Trigger: Calling GetLSPDiagnostics(ctx, id, lspName) when the server is unreachable, the base URL/host is wrong, the connection is refused or reset, the TLS handshake fails, or ctx is canceled before the response arrives.
Common situations: Running the client against a daemon that isn't started or has exited; pointing the client at the wrong port; a stale workspace id causing a redirect/proxy failure; network interruption between client and server; test environments with no local server.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- failed to get LSPs: %w
- failed to make request: %w
- failed to get MCP states: %w
- failed to get MCP pending auth: %w
- empty providers list from catwalk
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/3792096edfd6da19.
Report an issue: GitHub.