charmbracelet/crush · error
failed to get MCP states: status code %d
Error message
failed to get MCP states: status code %d
What it means
MCPGetStates got a non-200 HTTP status from /workspaces/{id}/mcp/states. The server responded but rejected the request; the code is embedded in the message. Useful for distinguishing 404 (bad id) from 401 (auth) or 5xx (server fault).
Source
Thrown at internal/client/proto.go:322
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get LSPs: status code %d", rsp.StatusCode)
}
var lsps map[string]proto.LSPClientInfo
if err := json.NewDecoder(rsp.Body).Decode(&lsps); err != nil {
return nil, fmt.Errorf("failed to decode LSPs: %w", err)
}
return lsps, nil
}
// MCPGetStates retrieves the MCP client states for a workspace.
func (c *Client) MCPGetStates(ctx context.Context, id string) (map[string]proto.MCPClientInfo, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/mcp/states", id), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get MCP states: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get MCP states: status code %d", rsp.StatusCode)
}
var states map[string]proto.MCPClientInfo
if err := json.NewDecoder(rsp.Body).Decode(&states); err != nil {
return nil, fmt.Errorf("failed to decode MCP states: %w", err)
}
return states, nil
}
// MCPPendingAuth retrieves the MCP servers awaiting OAuth authentication
// for a workspace.
func (c *Client) MCPPendingAuth(ctx context.Context, id string) ([]proto.MCPPendingAuthServer, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/mcp/pending-auth", id), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get MCP pending auth: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get MCP pending auth: status code %d", rsp.StatusCode)View on GitHub (pinned to 7944b8e522)
Solutions
- Branch on the status code: 404 -> refresh workspace id; 401/403 -> re-auth; >=500 -> inspect server logs.
- Validate the workspace id against a fresh GetWorkspace call before polling.
- Fix any broken MCP server configuration server-side if 500s persist.
- Update client/server to matching versions.
Example fix
// before
states, err := client.MCPGetStates(ctx, wsID)
// after
states, err := client.MCPGetStates(ctx, wsID)
if err != nil {
var statusErr *statusCodeError // if you wrap status codes
if errors.As(err, &statusErr) && statusErr.code == http.StatusNotFound {
return nil, fmt.Errorf("workspace %s not found", wsID)
}
return nil, err
} Defensive patterns
Strategy: fallback
Validate before calling
if _, err := client.GetWorkspace(ctx, wsID); err != nil { return fmt.Errorf("cannot query MCP states: invalid workspace: %w", err) } Type guard
func statusCodeFrom(err error) int {
var se interface{ StatusCode() int }
if err != nil && errors.As(err, &se) { return se.StatusCode() }
return 0
} Try / catch
states, err := client.MCPGetStates(ctx, wsID)
if err != nil {
switch statusCodeFrom(err) {
case http.StatusNotFound: return nil, nil // no workspace/MCP states — treat as empty
case http.StatusUnauthorized: return nil, retryAfterAuth(ctx)
default: return nil, err
}
} Prevention
- Refresh workspace ids when sessions restart instead of caching them.
- Handle 404 as an empty-state signal rather than an error.
- Re-authenticate automatically on 401/403.
- Investigate server logs for 500s caused by broken MCP configs.
When it happens
Trigger: Calling MCPGetStates with an unknown workspace id (404), invalid/expired credentials (401/403), or when the server errors while collecting MCP states (500).
Common situations: Workspace recreated with a new id; auth token rotated; MCP state collection panicking server-side due to a broken MCP server config; old client hitting a restructured endpoint.
Related errors
- failed to get LSP diagnostics: status code %d
- failed to get LSPs: status code %d
- session ID is required for creating a new file
- mcp '%s' not found in configuration
- mcp '%s' does not use OAuth authentication
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/7ae24ed28b7a9647.
Report an issue: GitHub.