{"id":"f926ee2ded57f97a","repo":"gofiber/fiber","slug":"sse-invalid-event-w","errorCode":null,"errorMessage":"sse: invalid event: %w","messagePattern":"sse: invalid event: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"middleware/sse/event.go","lineNumber":53,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar frame bytes.Buffer\n\n\tif event.ID != \"\" {\n\t\tid, err := sanitizeField(event.ID)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"sse: invalid id: %w\", err)\n\t\t}\n\t\tif id != \"\" {\n\t\t\tappendField(&frame, \"id\", id)\n\t\t}\n\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","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/sse/event.go#L35-L71","documentation":"writeEvent rejects an Event.Name (the SSE event field) containing CR or LF for the same wire-format reason as the id: a newline would terminate the field early. sanitizeField returns errInvalidField and the error is wrapped.","triggerScenarios":"Passing sse.Event{Name: \"user\\nupdate\"} or any name containing embedded CR/LF - typically from concatenating lines or unsanitized input.","commonSituations":"Building event names from user/DB strings; whitespace/newline artifacts in config; multi-token names joined with newlines.","solutions":["Restrict event names to a fixed set of single-line tokens (recommended SSE practice).","Sanitize any dynamic name by removing/replacing CR and LF."],"exampleFix":"// before\nstream.Event(sse.Event{Name: topic, Data: msg}) // topic may contain \\n\n\n// after\nname := strings.NewReplacer(\"\\r\\n\", \"\", \"\\r\", \"\", \"\\n\", \"\").Replace(topic)\nstream.Event(sse.Event{Name: name, Data: msg})","handlingStrategy":"validation","validationCode":"const validEventName = `^[A-Za-z0-9_.-]+$`\nvar nameRe = regexp.MustCompile(validEventName)\nfunc cleanEventName(s string) string {\n    s = strings.NewReplacer(\"\\r\", \"\", \"\\n\", \"\").Replace(s)\n    if !nameRe.MatchString(s) { return \"message\" }\n    return s\n}","typeGuard":null,"tryCatchPattern":"if err := stream.Event(ev); err != nil {\n    log.Warnf(\"dropping event with invalid name: %v\", err)\n}","preventionTips":["Use a closed set of event names (e.g. 'message','update').","Sanitize any dynamic name to remove CR/LF."],"tags":["sse","validation","fiber"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}