charmbracelet/crush · error
failed to get LSP diagnostics: status code %d
Error message
failed to get LSP diagnostics: status code %d
What it means
GetLSPDiagnostics received an HTTP response but the status code was not 200. The server processed the request and rejected it (bad path/id, auth, server error), so no diagnostics payload is decoded. The code is reported in the message.
Source
Thrown at internal/client/proto.go:288
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)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get LSPs: status code %d", rsp.StatusCode)
}View on GitHub (pinned to 7944b8e522)
Solutions
- Log/handle rsp status: confirm the workspace id exists via GetWorkspace and the LSP name matches one returned by GetLSPs.
- Re-authenticate if you received 401/403.
- Ensure the LSP server is started for that workspace before querying diagnostics.
- Check server logs for the 5xx cause if status >= 500.
Example fix
// before
diags, err := client.GetLSPDiagnostics(ctx, wsID, "gopls")
// after
diags, err := client.GetLSPDiagnostics(ctx, wsID, "gopls")
if err != nil {
if strings.Contains(err.Error(), "status code 404") {
return nil, fmt.Errorf("LSP %q not found in workspace %s", lspName, wsID)
}
return nil, err
} Defensive patterns
Strategy: fallback
Validate before calling
ws, err := client.GetWorkspace(ctx, wsID); if err != nil { return err }
lsps, err := client.GetLSPs(ctx, wsID); if err != nil { return err }
if _, ok := lsps[lspName]; !ok { return fmt.Errorf("LSP %q not running in workspace", lspName) } Type guard
func isStatusErr(err error) (int, bool) {
var se interface{ StatusCode() int }
if err != nil && errors.As(err, &se) { return se.StatusCode(), true }
return 0, false
} Try / catch
diags, err := client.GetLSPDiagnostics(ctx, wsID, lspName)
if err != nil {
if code, ok := isStatusErr(err); ok && code == http.StatusNotFound {
return emptyDiagnostics, nil // no LSP/diagnostics yet — degrade gracefully
}
return nil, err
} Prevention
- Confirm the LSP is started (GetLSPs) before querying its diagnostics.
- Handle 401 by refreshing credentials proactively.
- Keep client and server versions aligned so endpoints exist.
- Return empty diagnostics instead of failing when a status 404 means 'nothing yet'.
When it happens
Trigger: Calling GetLSPDiagnostics against a workspace id or lsp name that doesn't exist (404), an unauthorized/expired session (401/403), or a server-side crash (500) on the /workspaces/{id}/lsps/{lspName}/diagnostics endpoint.
Common situations: Typo in the LSP name or querying before the LSP has started; workspace session ended so the id is stale; proxy/auth middleware returning 401; server version lacking the diagnostics endpoint (404/405).
Related errors
- failed to get LSPs: status code %d
- failed to get MCP states: status code %d
- failed to read file: %w
- failed to get LSP diagnostics: %w
- failed to decode LSP diagnostics: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/f7de3ae7a411b7ce.
Report an issue: GitHub.