{"record":{"id":"7c4968b434eaa26a","repo":"charmbracelet/crush","slug":"failed-to-read-mcp-resource-w","errorCode":null,"errorMessage":"failed to read MCP resource: %w","messagePattern":"failed to read MCP resource: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/config.go","lineNumber":311,"sourceCode":"\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\n\tif err := json.NewDecoder(rsp.Body).Decode(&contents); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode MCP resource: %w\", err)\n\t}\n\treturn contents, nil\n}\n\nfunc (c *Client) ListMCPPrompts(ctx context.Context, id string) ([]proto.MCPPrompt, error) {\n\trsp, err := c.get(ctx, fmt.Sprintf(\"/workspaces/%s/mcp/prompts\", id), nil, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list MCP prompts: %w\", err)\n\t}\n\tdefer rsp.Body.Close()","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/config.go#L293-L329","documentation":"ReadMCPResource POSTs to /workspaces/{id}/mcp/read-resource to fetch a resource from a named MCP server and returns its contents. The error wraps any transport failure from c.post before the response status is inspected — the request never completed successfully.","triggerScenarios":"c.post fails: unreachable host, DNS/TLS errors, malformed workspace ID in the URL path, cancelled context, or request serialization failure.","commonSituations":"Coder daemon down; wrong base URL in client config; offline/VPN environment; context deadline exceeded while the MCP server was slow.","solutions":["Check connectivity to the Coder server and the configured base URL.","Validate the workspace ID used in the path.","Examine the wrapped error for the exact network cause.","Increase the context timeout for large or slow resources and retry."],"exampleFix":"// before\ncontents, err := client.ReadMCPResource(ctx, id, name, uri)\n// after\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\ncontents, err := client.ReadMCPResource(ctx, id, name, uri)\nif err != nil {\n    return nil, fmt.Errorf(\"read resource %s from %s: %w\", uri, name, err)\n}","handlingStrategy":"retry","validationCode":"func validateReadInput(workspaceID, server, uri string) error {\n    if workspaceID == \"\" || server == \"\" || uri == \"\" {\n        return errors.New(\"workspace ID, server name, and URI are required\")\n    }\n    if !strings.Contains(uri, \":\") {\n        return fmt.Errorf(\"resource URI %q is not a valid URI\", uri)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"ctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\ncontents, err := client.ReadMCPResource(ctx, id, name, uri)\nif err != nil {\n    if isTransient(err) { // network-level errors are retryable\n        contents, err = client.ReadMCPResource(ctx, id, name, uri)\n    }\n    if err != nil { return nil, fmt.Errorf(\"read %s: %w\", uri, err) }\n}","preventionTips":["Use bounded contexts with timeouts for resource reads.","Validate URIs and workspace IDs before issuing the request.","Treat transport errors as transient and retry with backoff.","Log the wrapped error to distinguish DNS vs connection vs TLS issues."],"tags":["network","http-client","mcp"],"backgroundTag":"http-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}