{"record":{"id":"d40a4b05f2acca5e","repo":"goreleaser/goreleaser","slug":"could-not-read-response-w","errorCode":null,"errorMessage":"could not read response: %w","messagePattern":"could not read response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pipe/mcp/mcp.go","lineNumber":185,"sourceCode":"\tpublishURL := p.registry + \"/v0/publish\"\n\n\treturn retryx.Do(ctx, ctx.Config.Retry, func() error {\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, publishURL, bytes.NewReader(jsonData))\n\t\tif err != nil {\n\t\t\treturn retryx.Unrecoverable(fmt.Errorf(\"could not create request: %w\", err))\n\t\t}\n\t\treq.Header.Set(\"Content-Type\", \"application/json\")\n\t\treq.Header.Set(\"Authorization\", \"Bearer \"+token)\n\n\t\tresp, err := http.DefaultClient.Do(req)\n\t\tif err != nil {\n\t\t\treturn retryx.HTTP(fmt.Errorf(\"could not send request: %w\", err), resp)\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not read response: %w\", err)\n\t\t}\n\n\t\tif resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK {\n\t\t\treturn retryx.HTTP(fmt.Errorf(\"got status code %d: %s\", resp.StatusCode, string(body)), resp)\n\t\t}\n\n\t\tvar serverResponse apiv0.ServerResponse\n\t\tif err := json.Unmarshal(body, &serverResponse); err != nil {\n\t\t\treturn fmt.Errorf(\"could not parse response: %w\", err)\n\t\t}\n\n\t\tlog.\n\t\t\tWithField(\"name\", server.Name).\n\t\t\tWithField(\"status\", serverResponse.Meta.Official.Status).\n\t\t\tInfo(\"published to MCP registry\")\n\t\tsummary.Appendf(\"Published `%s` to the MCP registry\", server.Name)\n\n\t\treturn nil","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/goreleaser/goreleaser/blob/f5edd7395693c0c6b501dc722d445d2e86af854d/internal/pipe/mcp/mcp.go#L167-L203","documentation":"After a successful HTTP round-trip, the MCP publish pipe reads the entire response body with io.ReadAll; if that fails, the body read failed mid-stream (connection dropped, truncated response). Notably this error is NOT wrapped in retryx.HTTP, so it is not retried and aborts the publish.","triggerScenarios":"io.ReadAll(resp.Body) errors while draining the /v0/publish response — the server closed the connection early, a proxy terminated the stream, or a chunked response was interrupted.","commonSituations":"An intermediary (load balancer, corporate proxy) kills long-lived responses; registry server under load resets the connection; flaky CI network dropping connections mid-response.","solutions":["Re-run the release; this is usually transient — if frequent, investigate the network path/proxy between the runner and the registry.","Check the registry server logs/load balancer timeout settings (idle/response timeouts that cut responses).","Ensure any proxy keeps the connection alive for the duration of the publish response.","Wrap the release step with an outer retry in CI if the registry is known to be flaky."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"could not read response\") {\n    // transient body-read failure: rerun the release or the publish step\n}","preventionTips":["Check proxy/load-balancer idle timeouts between runner and registry.","Re-run transient failures in CI with an outer job-level retry.","Monitor the registry's status/health endpoint during releases."],"tags":["http","io","response-body","mcp-registry","publish"],"backgroundTag":"response-body-read-failed","analyzedSha":"f5edd7395693c0c6b501dc722d445d2e86af854d","analyzedAt":"2026-09-05T09:57:18.807Z","contentChangedAt":"2026-09-05T09:57:18.807Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}