gofiber/fiber · error

sse: finish comment

Error message

sse: finish comment: %w

What it means

Thrown by writeComment when the final '\n' that terminates a (non-empty) comment cannot be written. This is the last write of the comment routine; failing here means the connection broke during comment emission — same class as 208/210.

Solutions

  1. Treat as end-of-stream; stop writing and return.
  2. Rely on the stream's closed/error state (stream.Err()) for cleanup decisions.

Example fix

// before
if err := stream.Comment(note); err != nil { log.Warn(err) /* ignore */ }
// after
if err := stream.Comment(note); err != nil { return }
Defensive patterns

Strategy: try-catch

Validate before calling

// Transport error — not locally preventable. Structure handler to bail on write error.

Try / catch

if err := stream.Comment(note); err != nil {
    return // trailing-newline write failed => connection gone
}

Prevention

When it happens

Trigger: Client disconnect, proxy reset, or broken pipe exactly during the trailing-newline write of a comment.

Common situations: Connection dying partway through a comment; intermediary closing the stream between writes.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/099eabc2e0d62df5. Report an issue: GitHub.

Appendix: source

Thrown at middleware/sse/event.go:86

	}
	return nil
}

func writeComment(w *bufio.Writer, comment string) error {
	comment = sanitizeComment(comment)
	if comment == "" {
		if _, err := w.WriteString(":\n\n"); err != nil {
			return fmt.Errorf("sse: write heartbeat: %w", err)
		}
		return nil
	}
	for line := range strings.SplitSeq(comment, "\n") {
		if _, err := fmt.Fprintf(w, ": %s\n", line); err != nil {
			return fmt.Errorf("sse: write comment: %w", err)
		}
	}
	if _, err := w.WriteString("\n"); err != nil {
		return fmt.Errorf("sse: finish comment: %w", err)
	}
	return nil
}

type eventPayload struct {
	data    string
	hasData bool
}

func eventData(data any, jsonMarshal utils.JSONMarshal) (eventPayload, error) {
	switch value := data.(type) {
	case nil:
		return eventPayload{}, nil
	case string:
		return eventPayload{data: value, hasData: true}, nil
	case []byte:
		return eventPayload{data: string(value), hasData: true}, nil
	case json.RawMessage:

View on GitHub (pinned to a105acad6c)