{"record":{"id":"d46e4eb05a276c7a","repo":"apache/beam","slug":"failed-to-encode-dofn-v-missing-fn","errorCode":null,"errorMessage":"failed to encode DoFn %v, missing fn","messagePattern":"failed to encode DoFn (.+?), missing fn","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/serialize.go","lineNumber":265,"sourceCode":"\t\tif _, ok := runtime.LookupType(k); !ok {\n\t\t\terr := errors.Errorf(\"receiver type %v must be registered\", t)\n\t\t\treturn nil, errors.WithContextf(err, \"encoding structural DoFn %v\", u)\n\t\t}\n\t\ttyp, err := encodeType(t)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrapf(err, \"failed to encode receiver type %T\", u.Recv)\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding structural DoFn %v\", u)\n\t\t}\n\n\t\tdata, err := jsonx.Marshal(u.Recv)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrapf(err, \"failed to marshal receiver %v\", u.Recv)\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding structural DoFn %v\", u)\n\t\t}\n\t\treturn &v1pb.Fn{Type: typ, Opt: string(data)}, nil\n\n\tdefault:\n\t\treturn nil, errors.Errorf(\"failed to encode DoFn %v, missing fn\", u)\n\t}\n}\n\nfunc decodeFn(u *v1pb.Fn) (*graph.Fn, error) {\n\tif u.Dynfn != nil {\n\t\tgen, err := runtime.ResolveFunction(u.Dynfn.Gen, genFnType)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrapf(err, \"bad symbol %v\", u.Dynfn.Gen)\n\t\t\treturn nil, errors.WithContextf(wrapped, \"decoding dynamic DoFn %v\", u)\n\t\t}\n\n\t\tt, err := decodeType(u.Dynfn.Type)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrap(err, \"bad type\")\n\t\t\treturn nil, errors.WithContextf(wrapped, \"failed to decode dynamic DoFn %v\", u)\n\t\t}\n\t\treturn graph.NewFn(&graph.DynFn{\n\t\t\tName: u.Dynfn.Name,","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/serialize.go#L247-L283","documentation":"encodeFn reached its default case: the graph.Fn did not contain a DynFn, UserFn, or a structural fn value it knows how to encode, so there is no encoding path for this DoFn. It indicates an Fn populated in a way the graphx encoder does not support.","triggerScenarios":"EncodeMultiEdge on a *graph.Fn whose Fn/T/receiver fields are all unset or hold an unsupported fn variant (default switch branch).","commonSituations":"Custom transforms constructing graph.Fn directly without setting a fn; internally-constructed Fn nodes from newer/older Beam versions with mismatched shapes.","solutions":["Build transforms with the public beam.ParDo/beam.Impulse APIs rather than hand-constructing graph.Fn.","Ensure the DoFn implements a supported form (named struct, func, or DynFn).","Check Beam version skew between the pipeline construction code and graphx serialization library.","Add debugging to print the graph.Fn before encoding to confirm which field is unset."],"exampleFix":"// before\nfn := &graph.Fn{} // nothing set\n\n// after\nfn, err := graph.NewFn(&myDoFn{}) // backed by a registered DoFn","handlingStrategy":"validation","validationCode":"if fn == nil || (fn.Dyn == nil && fn.Fn == nil && fn.T == nil) {\n    return fmt.Errorf(\"graph.Fn has no encodable fn payload\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := graph.NewFn(myDoFn{}); err != nil {\n    return fmt.Errorf(\"DoFn not constructible: %w\", err)\n}","preventionTips":["Construct Fn values via graph.NewFn or public beam APIs, never bare struct literals.","Pin all pipeline components to the same Beam SDK version."],"tags":["go","serialization","apache-beam"],"backgroundTag":"empty-required-field","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"}