{"record":{"id":"2555eb3023c151a7","repo":"gofiber/fiber","slug":"sse-marshal-data-w","errorCode":null,"errorMessage":"sse: marshal data: %w","messagePattern":"sse: marshal data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/sse/event.go","lineNumber":109,"sourceCode":"type eventPayload struct {\n\tdata    string\n\thasData bool\n}\n\nfunc eventData(data any, jsonMarshal utils.JSONMarshal) (eventPayload, error) {\n\tswitch value := data.(type) {\n\tcase nil:\n\t\treturn eventPayload{}, nil\n\tcase string:\n\t\treturn eventPayload{data: value, hasData: true}, nil\n\tcase []byte:\n\t\treturn eventPayload{data: string(value), hasData: true}, nil\n\tcase json.RawMessage:\n\t\treturn eventPayload{data: string(value), hasData: true}, nil\n\tdefault:\n\t\tencoded, err := jsonMarshal(value)\n\t\tif err != nil {\n\t\t\treturn eventPayload{}, fmt.Errorf(\"sse: marshal data: %w\", err)\n\t\t}\n\t\treturn eventPayload{data: string(encoded), hasData: true}, nil\n\t}\n}\n\nfunc jsonMarshalOrDefault(jsonMarshal []utils.JSONMarshal) utils.JSONMarshal {\n\tif len(jsonMarshal) > 0 && jsonMarshal[0] != nil {\n\t\treturn jsonMarshal[0]\n\t}\n\treturn json.Marshal\n}\n\nfunc appendField(w *bytes.Buffer, field, value string) {\n\tw.WriteString(field) //nolint:errcheck // bytes.Buffer writes never fail.\n\tw.WriteString(\": \")  //nolint:errcheck // bytes.Buffer writes never fail.\n\tw.WriteString(value) //nolint:errcheck // bytes.Buffer writes never fail.\n\tw.WriteByte('\\n')    //nolint:errcheck // bytes.Buffer writes never fail.\n}","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/sse/event.go#L91-L127","documentation":"Thrown by eventData when the Event.Data value is not one of the pass-through types (nil, string, []byte, json.RawMessage) and the configured JSON marshaler fails to encode it. The %w wraps the json.Marshal (or custom JSONMarshal) error. Data values of these special types bypass JSON; everything else is JSON-encoded, so a non-JSON-encodable value triggers this.","triggerScenarios":"Passing Event.Data as a func, channel, complex64/128, a struct with unexported fields of unsupported types, a value implementing json.Marshaler whose MarshalJSON returns an error, or a cyclic structure.","commonSituations":"Streaming a struct that contains a non-serializable field (e.g. a sync.Mutex, a *sql.DB, a func callback); passing a map with non-string keys; a custom MarshalJSON that errors on edge cases.","solutions":["Only pass JSON-encodable values as Event.Data.","For raw/preformatted payloads, pass a string or []byte (these bypass JSON entirely).","If you use a custom jsonMarshal (via app config or Stream.Event variadic), ensure it handles your types or returns a clear error.","Implement json.Marshaler correctly on custom types; test MarshalJSON separately."],"exampleFix":"// before\nstream.Event(sse.Event{Data: struct{ Cb func() }{}})\n// -> sse: marshal data: json: unsupported type: func()\n\n// after — pass a serializable DTO\nstream.Event(sse.Event{Data: MyDTO{ID: 1, Name: \"x\"}})\n// or send raw preformatted JSON\nstream.Event(sse.Event{Data: []byte(`{\"id\":1}`)})","handlingStrategy":"validation","validationCode":"// Pre-marshal to fail fast with a clear error before hitting the stream.\nfunc mustSSEData(v any) any {\n    switch v.(type) {\n    case nil, string, []byte, json.RawMessage:\n        return v\n    default:\n        if _, err := json.Marshal(v); err != nil {\n            log.Fatalf(\"Event.Data not JSON-encodable: %v\", err)\n        }\n        return v\n    }\n}","typeGuard":"func isJSONEncodable(v any) bool {\n    switch v.(type) {\n    case nil, string, []byte, json.RawMessage:\n        return true\n    }\n    _, err := json.Marshal(v)\n    return err == nil\n}","tryCatchPattern":"if !isJSONEncodable(ev.Data) {\n    ev.Data = []byte(`{\"error\":\"non-serializable payload\"}`)\n}\nif err := stream.Event(ev); err != nil { return }","preventionTips":["Only pass JSON-encodable values as Event.Data.","For preformatted payloads, pass string or []byte to bypass JSON.","Implement and test json.Marshaler on custom types.","If using a custom JSONMarshal, ensure it handles all your event types."],"tags":["sse","json","serialization","marshaling"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}