{"record":{"id":"c0f7942c2f2e78b8","repo":"gofiber/fiber","slug":"sse-write-event-w","errorCode":null,"errorMessage":"sse: write event: %w","messagePattern":"sse: write event: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/sse/event.go","lineNumber":67,"sourceCode":"\t}\n\tif event.Name != \"\" {\n\t\tname, err := sanitizeField(event.Name)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"sse: invalid event: %w\", err)\n\t\t}\n\t\tif name != \"\" {\n\t\t\tappendField(&frame, \"event\", name)\n\t\t}\n\t}\n\tif event.Retry > 0 {\n\t\tappendField(&frame, \"retry\", utils.FormatInt(event.Retry.Milliseconds()))\n\t}\n\tif data.hasData {\n\t\tappendData(&frame, data.data)\n\t}\n\tframe.WriteByte('\\n') //nolint:errcheck // bytes.Buffer writes never fail.\n\tif _, err := w.Write(frame.Bytes()); err != nil {\n\t\treturn fmt.Errorf(\"sse: write event: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc writeComment(w *bufio.Writer, comment string) error {\n\tcomment = sanitizeComment(comment)\n\tif comment == \"\" {\n\t\tif _, err := w.WriteString(\":\\n\\n\"); err != nil {\n\t\t\treturn fmt.Errorf(\"sse: write heartbeat: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n\tfor line := range strings.SplitSeq(comment, \"\\n\") {\n\t\tif _, err := fmt.Fprintf(w, \": %s\\n\", line); err != nil {\n\t\t\treturn fmt.Errorf(\"sse: write comment: %w\", err)\n\t\t}\n\t}\n\tif _, err := w.WriteString(\"\\n\"); err != nil {","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/sse/event.go#L49-L85","documentation":"Thrown by writeEvent when writing the fully-assembled SSE frame to the bufio.Writer (the HTTP response body writer) fails. The %w wraps the underlying network write error. By the time this fires, the frame itself is valid; the problem is the transport — almost always a disconnected or reset client connection.","triggerScenarios":"The client has closed the connection (tab closed, navigation away), an intermediary proxy/load-balancer timed out and reset the stream, a mobile network dropped, or a broken-pipe/EOF occurred during the write.","commonSituations":"Long-lived SSE streams where the client goes away silently; reverse proxies with short idle timeouts; flaky mobile networks; clients that hard-close without sending a close frame.","solutions":["Treat this as a normal stream-termination: stop writing and return; do not retry writes on a broken stream.","After the handler returns, consult stream.Err() / the stream context to decide cleanup.","Ensure your reverse proxy/idle timeouts are longer than your heartbeat interval so intermediaries don't kill idle streams.","Use the heartbeat (DisableHeartbeat=false) so dead connections are detected proactively."],"exampleFix":"// before\nfor { if err := stream.Event(ev); err != nil { log.Error(err); continue } }\n// after\ndone := stream.Context().Done()\nfor {\n    select {\n    case <-done:\n        return // client gone, stop cleanly\n    default:\n        if err := stream.Event(ev); err != nil { return }\n    }\n}","handlingStrategy":"try-catch","validationCode":"// There is nothing to validate locally; the failure is a dead socket.\n// Instead, structure the handler to respect the stream lifecycle:\nfunc streamHandler(c fiber.Ctx, s *sse.Stream) error {\n    ctx := s.Context()\n    for {\n        select {\n        case <-ctx.Done():\n            return nil // client gone\n        case ev := <-events:\n            if err := s.Event(ev); err != nil { return nil }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := stream.Event(ev); err != nil {\n    // write failed => connection is gone; stop producing events\n    return\n}","preventionTips":["Always check the stream context (Context().Done()) and stop when it cancels.","Set HeartbeatInterval shorter than your reverse-proxy idle timeout.","Do not retry a failed write — the stream is closed by failLocked.","Log stream.Err() in OnClose to distinguish clean vs error teardown."],"tags":["sse","network","write","disconnected"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}