{"record":{"id":"a2d4b908245f2563","repo":"gofr-dev/gofr","slug":"stream-value-could-not-be-encoded","errorCode":null,"errorMessage":"stream value could not be encoded","messagePattern":"stream value could not be encoded","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/http/stream.go","lineNumber":21,"sourceCode":"import (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\tresTypes \"gofr.dev/pkg/gofr/http/response\"\n)\n\nconst (\n\tdefaultHeartbeat  = 15 * time.Second\n\tstreamWriteWindow = 30 * time.Second\n)\n\nvar (\n\terrStreamPanic   = errors.New(\"stream source panicked\")\n\terrNilStream     = errors.New(\"stream source is nil\")\n\terrStreamCorrupt = errors.New(\"stream value could not be encoded\")\n)\n\n// handleStream drains s.Source to the client, flushing after every write. It pulls values on\n// demand so a slow client throttles the producer, sends a periodic keep-alive so a dropped client\n// is detected while idle, bounds each write with a deadline, and always closes the source — leaving\n// no goroutine behind when the client disconnects mid-stream. A Source that also honors its own\n// context cancels promptly even without a heartbeat.\nfunc (r Responder) handleStream(s resTypes.Stream) {\n\tif s.Source == nil {\n\t\tr.w.WriteHeader(http.StatusInternalServerError)\n\t\t_, _ = r.w.Write([]byte(`{\"error\":{\"message\":\"` + errNilStream.Error() + `\"}}` + \"\\n\"))\n\n\t\treturn\n\t}\n\n\trc := http.NewResponseController(r.w)\n\n\tsetStreamHeaders(r.w, s.Format)","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/http/stream.go#L3-L39","documentation":"errStreamCorrupt is returned by writeFrame in pkg/gofr/http/stream.go when a value pulled from the stream source cannot be encoded into a stream frame. The stream is aborted rather than sending a malformed or partial frame to the client.","triggerScenarios":"A Streamer emits a value that the frame encoder cannot serialize (unsupported type, value containing channels/funcs/cyclic references) so writeFrame's encoding step fails and returns errStreamCorrupt.","commonSituations":"Streaming arbitrary Go values (e.g. structs with unexported fields the encoder rejects, or values that fail JSON-style marshaling); changing a streamed struct to include an unencodable field; emitting non-primitive types from a generic source.","solutions":["Make the streamed values encodable: use plain structs with exported fields and JSON-safe types","Wrap or convert problematic values to encodable representations inside your Streamer before sending them on the channel","Log the offending value to identify which item in the stream is corrupt","Add a test streaming representative values end-to-end to catch encoding failures early"],"exampleFix":"// before\nitems <- func() {} // unencodable value -> errStreamCorrupt\n// after\nitems <- map[string]string{\"status\": \"ok\"} // encodable value","handlingStrategy":"type-guard","validationCode":"func encodable(v any) error {\n    rv := reflect.ValueOf(v)\n    switch rv.Kind() {\n    case reflect.Chan, reflect.Func, reflect.UnsafePointer:\n        return fmt.Errorf(\"value of type %T is not encodable\", v)\n    }\n    return nil\n}","typeGuard":"func isStreamCorrupt(err error) bool {\n    return errors.Is(err, errStreamCorrupt)\n}","tryCatchPattern":"err := streamValues(w, src)\nif err != nil {\n    if errors.Is(err, errStreamCorrupt) {\n        log.Printf(\"dropping unencodable stream value: %v\", err)\n        return errStreamingAborted\n    }\n    return err\n}","preventionTips":["Stream only plain, exported-field structs and primitives","Scrub values in the Streamer before pushing to the channel","Add integration tests that encode representative values","Avoid sending funcs, channels, or cyclic references in streams"],"tags":["streaming","serialization"],"backgroundTag":"stream-value-encoding-failed","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}