{"record":{"id":"07593c2fc6dfe76f","repo":"charmbracelet/crush","slug":"failed-to-decode-mcp-resource-w","errorCode":null,"errorMessage":"failed to decode MCP resource: %w","messagePattern":"failed to decode MCP resource: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/config.go","lineNumber":319,"sourceCode":"\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()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to list MCP prompts: status code %d\", rsp.StatusCode)\n\t}\n\tvar prompts []proto.MCPPrompt\n\tif err := json.NewDecoder(rsp.Body).Decode(&prompts); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode MCP prompts: %w\", err)\n\t}\n\treturn prompts, nil","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/config.go#L301-L337","documentation":"After a successful 200 response, ReadMCPResource decodes the body into []MCPResourceContents. 'failed to decode MCP resource: %w' means the body was not the expected JSON array — a client/server API mismatch or a proxy HTML error page.","triggerScenarios":"json.Decode fails: server returned a different schema (version skew), an HTML error page from a reverse proxy, truncated body, or empty response.","commonSituations":"Client and Coder server versions out of sync; an auth proxy or load balancer intercepting and returning HTML; resource contents shape changed in a newer server release.","solutions":["Check client/server version compatibility and align versions.","Dump the raw response body (curl the endpoint) to see what was actually returned.","Confirm no proxy is mangling responses (look for HTML in the error).","Retry; transient truncation can also cause decode failures."],"exampleFix":"// before\ncontents, err := client.ReadMCPResource(ctx, id, name, uri)\n// after\ncontents, err := client.ReadMCPResource(ctx, id, name, uri)\nif err != nil && strings.Contains(err.Error(), \"failed to decode MCP resource\") {\n    return nil, fmt.Errorf(\"incompatible server response for resource %q — verify client/server versions: %w\", uri, err)\n}","handlingStrategy":"type-guard","validationCode":"// sanity-check client/server compatibility at startup\nver, err := client.BuildInfo(ctx)\nif err != nil || !compatibleVersions(clientVersion, ver.ExternalURL) {\n    return errors.New(\"coder client and server versions are incompatible\")\n}","typeGuard":"func isDecodeError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to decode MCP resource\")\n}\n// usage: if isDecodeError(err) { /* treat as schema/proxy mismatch, not transient */ }","tryCatchPattern":"contents, err := client.ReadMCPResource(ctx, id, name, uri)\nif isDecodeError(err) {\n    // non-retryable: inspect raw response, check versions, rule out proxies\n    return nil, fmt.Errorf(\"unexpected response shape from server: %w\", err)\n}\nif err != nil { return nil, err }","preventionTips":["Keep client and server versions aligned.","Verify no auth proxy or WAF returns HTML with 200 status.","When upgrading the server, regenerate/update client types.","Spot-check the endpoint with curl after server upgrades."],"tags":["json","decoding","version-skew"],"backgroundTag":"json-decode-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}