{"record":{"id":"ce61eb421f2c2b6c","repo":"gofiber/fiber","slug":"failed-to-write-response-body-to-writer-w","errorCode":null,"errorMessage":"failed to write response body to writer: %w","messagePattern":"failed to write response body to writer: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/response.go","lineNumber":220,"sourceCode":"\n\t\t// Create and write to file\n\t\toutFile, err := os.Create(file)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create file: %w\", err)\n\t\t}\n\t\tdefer func() { _ = outFile.Close() }() //nolint:errcheck // not needed\n\n\t\t// Use BodyStream() which handles both streaming and non-streaming cases\n\t\tif _, err = io.Copy(outFile, r.BodyStream()); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write response body to file: %w\", err)\n\t\t}\n\n\t\treturn nil\n\n\tcase io.Writer:\n\t\t// Use BodyStream() which handles both streaming and non-streaming cases\n\t\tif _, err := io.Copy(p, r.BodyStream()); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write response body to writer: %w\", err)\n\t\t}\n\t\t// Close the writer if it implements io.WriteCloser\n\t\tif pc, ok := p.(io.WriteCloser); ok {\n\t\t\t_ = pc.Close() //nolint:errcheck // not needed\n\t\t}\n\n\t\treturn nil\n\n\tdefault:\n\t\treturn ErrNotSupportSaveMethod\n\t}\n}\n\n// Reset clears the Response object, making it ready for reuse.\nfunc (r *Response) Reset() {\n\tr.client = nil\n\tr.request = nil\n\tr.respondedHost = resetOriginBuf(r.respondedHost)","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/client/response.go#L202-L238","documentation":"Response.Save, given an io.Writer, copies the body stream into it with io.Copy. This wraps a failure of that copy: a read error from the response body or a write error from the supplied writer (closed pipe, buffer overflow, custom Writer erroring).","triggerScenarios":"Passing a *pipe.Writer whose read end is closed; a bytes.Buffer that hits allocation limits; an HTTP response writer that has already been flushed/closed; a custom Writer returning an error; the upstream connection resetting mid-stream.","commonSituations":"Writing into an http.ResponseWriter after the client disconnected; piping into a process whose stdin closed; a streaming consumer that errors on a specific payload; network drops mid-copy.","solutions":["Inspect the wrapped cause to tell reader-side (network) from writer-side (your Writer) failures.","Ensure the Writer remains open and writable for the entire Save call; do not close it beforehand.","For long streams, set appropriate timeouts and propagate context cancellation cleanly."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isWriteCloser(v any) (io.Writer, bool) {\n    w, ok := v.(io.Writer)\n    return w, ok\n}","tryCatchPattern":"if _, err := io.Copy(w, r.BodyStream()); err != nil {\n    if errors.Is(err, io.ErrClosedPipe) || errors.Is(err, syscall.EPIPE) {\n        // writer closed before body finished; abort cleanly\n    }\n    return err\n}","preventionTips":["Keep the supplied Writer open and writable for the whole Save call.","Distinguish reader-side (network) from writer-side (your Writer) errors via the wrapped cause.","Propagate context cancellation to avoid writing into a dead sink."],"tags":["client","response","save","io","writer","streaming"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}