{"record":{"id":"b9f416675cbdbe75","repo":"chenhg5/cc-connect","slug":"googlechat-close-response-body-w","errorCode":null,"errorMessage":"googlechat: close response body: %w","messagePattern":"googlechat: close response body: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/googlechat/googlechat.go","lineNumber":439,"sourceCode":"\turl, body, err := buildSendRequest(rc, content)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"googlechat: build request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := p.doRequest(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err := io.Copy(io.Discard, resp.Body); err != nil {\n\t\t_ = resp.Body.Close()\n\t\treturn fmt.Errorf(\"googlechat: drain response body: %w\", err)\n\t}\n\tif err := resp.Body.Close(); err != nil {\n\t\treturn fmt.Errorf(\"googlechat: close response body: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (p *Platform) Reply(ctx context.Context, rctx any, content string) error {\n\treturn p.post(ctx, rctx, content)\n}\n\nfunc (p *Platform) Send(ctx context.Context, rctx any, content string) error {\n\treturn p.post(ctx, rctx, content)\n}\n\n// uploadAttachment uploads raw bytes to the Chat media endpoint using a\n// multipart/related request and returns the attachmentDataRef resource name.\nfunc (p *Platform) uploadAttachment(ctx context.Context, space, filename, mimeType string, data []byte) (string, error) {\n\tbuf := bytes.NewBuffer(make([]byte, 0, 256+len(data)))\n\tmw := multipart.NewWriter(buf)\n","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/googlechat.go#L421-L457","documentation":"This error is returned by the googlechat platform's internal post() helper when resp.Body.Close() fails after a successful HTTP response has been fully drained. The Go http package can report errors on close for responses with connection teardown issues; the library surfaces it wrapped with googlechat: context so callers know the message was likely delivered but cleanup failed. It propagates up through Reply and Send.","triggerScenarios":"Calling Reply() or Send() on the Google Chat platform; the POST to the Chat API succeeds, io.Copy(io.Discard, resp.Body) succeeds, but resp.Body.Close() returns a non-nil error (rare — typically connection reuse/teardown failure under flaky networks).","commonSituations":"Flaky network connections or HTTP/2 stream resets between the process and googleapis.com; proxy or firewall interference mid-response; client transport issues when the connection is returned to the pool.","solutions":["Retry the send; in most cases the message was already delivered and only body close failed.","Check network stability/DNS/proxy settings between the host and googleapis.com.","Upgrade the Go HTTP client/transport configuration (e.g. DisableKeepAlives) if close errors recur on connection reuse.","Log and monitor occurrences — if frequent it indicates transport-level problems, not API misuse."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := p.Send(ctx, target, msg); err != nil {\n    if strings.Contains(err.Error(), \"close response body\") {\n        // message likely delivered; log at warn and continue\n        slog.Warn(\"googlechat: response body close failed (likely delivered)\", \"err\", err)\n        return nil\n    }\n    return err\n}","preventionTips":["Monitor logs for this error to detect transport-level network instability.","Keep the Go runtime and HTTP transport up to date.","Avoid proxies that aggressively reset keep-alive connections to googleapis.com.","Treat close errors as non-fatal for delivery but alert on frequency."],"tags":["googlechat","http","network","response-body"],"backgroundTag":"response-body-close-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}