{"record":{"id":"40e5b6884267441c","repo":"charmbracelet/crush","slug":"failed-to-refresh-mcp-tools-status-code-d","errorCode":null,"errorMessage":"failed to refresh MCP tools: status code %d","messagePattern":"failed to refresh MCP tools: status code (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/config.go","lineNumber":299,"sourceCode":"\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to disable docker MCP: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// RefreshMCPTools refreshes tools for a named MCP server.\nfunc (c *Client) RefreshMCPTools(ctx context.Context, id, name string) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/mcp/refresh-tools\", id), nil, jsonBody(struct {\n\t\tName string `json:\"name\"`\n\t}{Name: name}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to refresh MCP tools: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to refresh MCP tools: status code %d\", rsp.StatusCode)\n\t}\n\treturn nil\n}\n\n// ReadMCPResource reads a resource from a named MCP server.\nfunc (c *Client) ReadMCPResource(ctx context.Context, id, name, uri string) ([]MCPResourceContents, error) {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/mcp/read-resource\", id), nil, jsonBody(struct {\n\t\tName string `json:\"name\"`\n\t\tURI  string `json:\"uri\"`\n\t}{Name: name, URI: uri}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read MCP resource: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to read MCP resource: status code %d\", rsp.StatusCode)\n\t}\n\tvar contents []MCPResourceContents","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/config.go#L281-L317","documentation":"RefreshMCPTools expects the server to answer 200 OK after refreshing MCP tools. Any other status (4xx/5xx) produces 'failed to refresh MCP tools: status code %d'. The body is not read, so the status number is the only diagnostic the client surfaces.","triggerScenarios":"Server returns non-200 to POST /workspaces/{id}/mcp/refresh-tools: 401/403 (bad or expired session token), 404 (wrong workspace ID or server version lacking the endpoint), 500 (server failed to reach the MCP server), 409/423 (workspace not running).","commonSituations":"Session cookie/API key expired; workspace stopped or building when tools were refreshed; older Coder server without the refresh-tools route; MCP server offline so the backend returns 500.","solutions":["Check the status code: 401/403 → re-authenticate; 404 → verify workspace ID and server version; 5xx → check server logs.","Ensure the workspace is running before refreshing tools.","Upgrade/downgrade the client to match the server's API version.","Retry after the MCP server is confirmed healthy."],"exampleFix":"// before\nerr := client.RefreshMCPTools(ctx, id, name)\n// after\nif err := client.RefreshMCPTools(ctx, id, name); err != nil {\n    if strings.Contains(err.Error(), \"status code 4\") {\n        // re-authenticate then retry\n        if err := login(ctx); err != nil { return err }\n        err = client.RefreshMCPTools(ctx, id, name)\n    }\n    if err != nil { return err }\n}","handlingStrategy":"try-catch","validationCode":"// confirm workspace is running and auth is valid beforehand\nws, err := client.Workspace(ctx, workspaceID)\nif err != nil || ws.LatestBuild.Status != \"running\" {\n    return errors.New(\"workspace must be running before refreshing MCP tools\")\n}","typeGuard":null,"tryCatchPattern":"if err := client.RefreshMCPTools(ctx, id, name); err != nil {\n    var code int\n    if n, _ := fmt.Sscanf(err.Error(), \"failed to refresh MCP tools: status code %d\", &code); n == 1 {\n        switch {\n        case code == 401 || code == 403:\n            // re-authenticate and retry\n        case code == 404:\n            // wrong workspace/name — surface to user\n        default:\n            // retry server-side (5xx) with backoff\n        }\n    }\n    return err\n}","preventionTips":["Keep the session token fresh; re-authenticate on 401/403.","Only call refresh-tools while the workspace is running.","Match client version to server version so the endpoint exists.","Parse the embedded status code and branch on it rather than treating all failures alike."],"tags":["http","status-code","mcp"],"backgroundTag":"unexpected-http-status","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}