{"record":{"id":"aa2246789315877f","repo":"apache/beam","slug":"bad-return-type","errorCode":null,"errorMessage":"bad return type","messagePattern":"bad return type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/serialize.go","lineNumber":479,"sourceCode":"\t\t\tfields = append(fields, field)\n\t\t}\n\t\treturn &v1pb.Type{Kind: v1pb.Type_STRUCT, Fields: fields}, nil\n\n\tcase reflect.Func:\n\t\tvar in []*v1pb.Type\n\t\tfor i := 0; i < t.NumIn(); i++ {\n\t\t\tparam, err := encodeType(t.In(i))\n\t\t\tif err != nil {\n\t\t\t\twrapped := errors.Wrap(err, \"bad parameter type\")\n\t\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding function %v\", t)\n\t\t\t}\n\t\t\tin = append(in, param)\n\t\t}\n\t\tvar out []*v1pb.Type\n\t\tfor i := 0; i < t.NumOut(); i++ {\n\t\t\tret, err := encodeType(t.Out(i))\n\t\t\tif err != nil {\n\t\t\t\twrapped := errors.Wrap(err, \"bad return type\")\n\t\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding function %v\", t)\n\t\t\t}\n\t\t\tout = append(out, ret)\n\t\t}\n\t\treturn &v1pb.Type{Kind: v1pb.Type_FUNC, ParameterTypes: in, ReturnTypes: out, IsVariadic: t.IsVariadic()}, nil\n\n\tcase reflect.Chan:\n\t\telm, err := encodeType(t.Elem())\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrap(err, \"bad element type\")\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding channel %v\", t)\n\t\t}\n\t\tdir, err := encodeChanDir(t.ChanDir())\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrap(err, \"bad channel direction\")\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding channel %v\", t)\n\t\t}\n\t\treturn &v1pb.Type{Kind: v1pb.Type_CHAN, Element: elm, ChanDir: dir}, nil","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/serialize.go#L461-L497","documentation":"encodeType serializes func types by encoding each return type; 'bad return type' means one of the function's output types failed to encode. Like the parameter-side error, it surfaces when exporting a DoFn or user function whose emit/output types cannot be represented on the wire.","triggerScenarios":"A user function returns (or emits via a func outlet parameter) a type that encodeType cannot encode: map/array returns, structs with unexported fields, or unregistered custom types.","commonSituations":"DoFns emitting map results; builders returning structs with private fields; pipelines exported for Flink/Dataflow/Spark runners.","solutions":["Change the return/emitted type to an encodable form (slice of exported-field structs).","Register the custom output type in the Beam type registry.","Split emission into encodable sub-values (emit each map entry as a KV struct).","Use the 'encoding function %v' context message to identify the failing signature."],"exampleFix":"// before\nfunc parse(line string) map[string]string { ... }\n// after\ntype Field struct { K, V string }\nfunc parse(line string) []Field { ... }","handlingStrategy":"validation","validationCode":"ft := reflect.TypeOf(fn)\nfor i := 0; i < ft.NumOut(); i++ {\n    if err := isEncodableType(ft.Out(i)); err != nil {\n        return fmt.Errorf(\"return %d of %v unencodable: %w\", i, ft, err)\n    }\n}","typeGuard":"func encodableReturns(fn any) bool { t := reflect.TypeOf(fn); if t.Kind() != reflect.Func { return false }; for i := 0; i < t.NumOut(); i++ { if isEncodableType(t.Out(i)) != nil { return false } }; return true }","tryCatchPattern":"if !encodableReturns(fn) {\n    return fmt.Errorf(\"function %T returns unserializable types\", fn)\n}","preventionTips":["Return slices/structs of exported fields, never maps or arrays","Emit KV structs instead of map results from DoFns","Test each DoFn's signature against encodeType in unit tests"],"tags":["go","apache-beam","serialization","function-signature"],"backgroundTag":"unencodable-reflect-type","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}