{"record":{"id":"4eb2bdb81fafe33c","repo":"charmbracelet/crush","slug":"failed-to-get-lsps-status-code-d","errorCode":null,"errorMessage":"failed to get LSPs: status code %d","messagePattern":"failed to get LSPs: status code (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/proto.go","lineNumber":305,"sourceCode":"\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}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get LSPs: status code %d\", rsp.StatusCode)\n\t}\n\tvar lsps map[string]proto.LSPClientInfo\n\tif err := json.NewDecoder(rsp.Body).Decode(&lsps); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode LSPs: %w\", err)\n\t}\n\treturn lsps, nil\n}\n\n// MCPGetStates retrieves the MCP client states for a workspace.\nfunc (c *Client) MCPGetStates(ctx context.Context, id string) (map[string]proto.MCPClientInfo, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/mcp/states\", id), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get MCP states: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get MCP states: status code %d\", rsp.StatusCode)\n\t}","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/proto.go#L287-L323","documentation":"GetLSPs got an HTTP response whose status code was not 200 from /workspaces/{id}/lsps. The server deliberately rejected the request; the numeric status is included in the message. No LSP state map is returned.","triggerScenarios":"Calling GetLSPs/LSPGetStates with a nonexistent workspace id (404), expired auth (401/403), a server fault (500), or a client/server version mismatch where the lsps endpoint moved (404/405).","commonSituations":"Workspace closed/timed out on the server side; querying with an id from a previous session; reverse proxy returning 401; running an older client against a newer server.","solutions":["Check the status code in the message and handle 404 by refreshing the workspace id (re-create or list workspaces).","Re-authenticate for 401/403 responses.","Restart the server / check server logs for 5xx errors.","Align client and server versions so the endpoint exists."],"exampleFix":"// before\nlsps, err := client.GetLSPs(ctx, staleWsID)\n// after\nws, err := client.GetWorkspace(ctx, currentWsID)\nif err != nil { return nil, err }\nlsps, err := client.GetLSPs(ctx, ws.ID)\nif err != nil {\n    if isNotFoundStatus(err) { return nil, fmt.Errorf(\"workspace %s gone; re-open it\", currentWsID) }\n    return nil, err\n}","handlingStrategy":"validation","validationCode":"ws, err := client.GetWorkspace(ctx, wsID)\nif err != nil { return fmt.Errorf(\"workspace %s invalid before GetLSPs: %w\", wsID, err) }","typeGuard":"func isNotFoundStatus(err error) bool {\n\tvar se interface{ StatusCode() int }\n\treturn err != nil && errors.As(err, &se) && (se.StatusCode() == 404 || se.StatusCode() == 410)\n}","tryCatchPattern":"lsps, err := client.GetLSPs(ctx, wsID)\nif err != nil {\n\tif isNotFoundStatus(err) {\n\t\treturn nil, ErrWorkspaceGone // caller recreates/reopens the workspace\n\t}\n\treturn nil, err\n}","preventionTips":["Always resolve the workspace id from a live session rather than caching it across restarts.","Treat 404 as 're-open the workspace', not a fatal error.","Re-authenticate on 401/403 before retrying.","Check server logs when statuses are 5xx."],"tags":["http-status","lsp","api","go"],"backgroundTag":"http-non-200-status","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}