{"record":{"id":"876ef086c0566a3a","repo":"apache/beam","slug":"failed-to-decode-userfn","errorCode":null,"errorMessage":"failed to decode userfn","messagePattern":"failed to decode userfn","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/serialize.go","lineNumber":292,"sourceCode":"\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,\n\t\t\tT:    t,\n\t\t\tData: u.Dynfn.Data,\n\t\t\tGen:  gen.(func(string, reflect.Type, []byte) reflectx.Func),\n\t\t})\n\t}\n\tif u.Fn != nil {\n\t\tfn, err := decodeUserFn(u.Fn)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrap(err, \"failed to decode userfn\")\n\t\t\treturn nil, errors.WithContextf(wrapped, \"decoding DoFn %v\", u)\n\t\t}\n\t\tfx, err := funcx.New(reflectx.MakeFunc(fn))\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrap(err, \"failed to construct userfn\")\n\t\t\treturn nil, errors.WithContextf(wrapped, \"decoding DoFn %v\", u)\n\t\t}\n\t\treturn &graph.Fn{Fn: fx}, nil\n\t}\n\n\tt, err := decodeType(u.Type)\n\tif err != nil {\n\t\twrapped := errors.Wrap(err, \"bad type\")\n\t\treturn nil, errors.WithContextf(wrapped, \"decoding structural DoFn %v\", u)\n\t}\n\telem := reflect.New(t)\n\tif err := jsonx.UnmarshalFrom(elem.Interface(), strings.NewReader(u.Opt)); err != nil {\n\t\twrapped := errors.Wrap(err, \"bad struct encoding\")","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/serialize.go#L274-L310","documentation":"decodeFn fails while decoding the Fn's userfn sub-message via decodeUserFn (a protobuf decode of the encoded function descriptor), wrapped as \"failed to decode userfn\". The serialized function payload in the pipeline proto is corrupt or from an incompatible schema version.","triggerScenarios":"DecodeMultiEdge decoding a Fn whose u.Fn payload fails proto unmarshaling or refers to symbols/types that cannot be resolved inside decodeUserFn.","commonSituations":"Pipeline proto produced by a different Beam version than the decoder; truncated/corrupted job submission graph; manually edited or cached pipeline files.","solutions":["Regenerate the pipeline with the same Beam Go SDK version used by the worker/decoder.","Check the inner cause of the wrap for the specific unresolvable symbol or type and register it.","Avoid hand-editing or caching serialized pipeline protos across releases.","If the pipeline comes from a file, re-export it from the driver rather than reusing stale artifacts."],"exampleFix":"// before\ngolang \"github.com/apache/beam/sdks/v2@v2.30.0/go/pkg/beam\"\n// worker compiled against v2.50.0\n\n// after\n// pin both driver and worker to the same Beam version, e.g. v2.50.0","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"fn, err := decodeUserFn(u.Fn)\nif err != nil {\n    return fmt.Errorf(\"userfn decode failed (check Beam SDK version parity between submitter and worker): %w\", err)\n}","preventionTips":["Use identical Beam Go SDK versions in driver and worker images.","Never reuse serialized pipeline protos across SDK upgrades.","Log the inner cause to identify the unresolvable symbol and register it in the worker."],"tags":["go","deserialization","protobuf","apache-beam"],"backgroundTag":"protobuf-unmarshal-failed","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"}