{"record":{"id":"3792096edfd6da19","repo":"charmbracelet/crush","slug":"failed-to-get-lsp-diagnostics-w","errorCode":null,"errorMessage":"failed to get LSP diagnostics: %w","messagePattern":"failed to get LSP diagnostics: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":284,"sourceCode":"}\n\nfunc sendEvent(ctx context.Context, evc chan any, ev any) bool {\n\tif ctx.Err() != nil {\n\t\treturn false\n\t}\n\tselect {\n\tcase evc <- ev:\n\t\treturn true\n\tcase <-ctx.Done():\n\t\treturn false\n\t}\n}\n\n// GetLSPDiagnostics retrieves LSP diagnostics for a specific LSP client.\nfunc (c *Client) GetLSPDiagnostics(ctx context.Context, id string, lspName string) (map[protocol.DocumentURI][]protocol.Diagnostic, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/lsps/%s/diagnostics\", id, lspName), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get LSP diagnostics: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get LSP diagnostics: status code %d\", rsp.StatusCode)\n\t}\n\tvar diagnostics map[protocol.DocumentURI][]protocol.Diagnostic\n\tif err := json.NewDecoder(rsp.Body).Decode(&diagnostics); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode LSP diagnostics: %w\", err)\n\t}\n\treturn diagnostics, nil\n}\n\n// GetLSPs retrieves the LSP client states for a workspace.\nfunc (c *Client) GetLSPs(ctx context.Context, id string) (map[string]proto.LSPClientInfo, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/lsps\", id), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get LSPs: %w\", err)\n\t}","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L266-L302","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif !isServerRunning() { /* proceed anyway */ }\ndiags, err := client.GetLSPDiagnostics(ctx, wsID, \"gopls\")\n// after\nif !isServerRunning() { return nil, fmt.Errorf(\"crush server not running at %s\", baseURL) }\nctx, cancel := context.WithTimeout(ctx, 10*time.Second)\ndefer cancel()\ndiags, err := client.GetLSPDiagnostics(ctx, wsID, \"gopls\")\nif err != nil { return nil, fmt.Errorf(\"GetLSPDiagnostics: %w\", err) }","handlingStrategy":"try-catch","validationCode":"if !serverReachable(baseURL) { return fmt.Errorf(\"crush server unreachable at %s\", baseURL) }\nif wsID == \"\" || lspName == \"\" { return errors.New(\"workspace id and lsp name are required\") }","typeGuard":"func isTransportErr(err error) bool {\n\tvar ne net.Error\n\treturn err != nil && (errors.As(err, &ne) || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded))\n}","tryCatchPattern":"diags, err := client.GetLSPDiagnostics(ctx, wsID, lspName)\nif err != nil {\n\tif isTransportErr(err) {\n\t\t// server down / network issue — surface or retry with backoff\n\t\treturn nil, fmt.Errorf(\"LSP diagnostics unavailable: %w\", err)\n\t}\n\treturn nil, err\n}","preventionTips":["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."],"tags":["network","http-client","lsp","go"],"backgroundTag":"http-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}