{"record":{"id":"7397059699efaebc","repo":"apache/beam","slug":"method-v-invalid","errorCode":null,"errorMessage":"method %v invalid","messagePattern":"method (.+?) invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":123,"sourceCode":"\t\t// Note that a ptr receiver is necessary if struct fields are updated in the\n\t\t// user code. Otherwise, updates are simply lost.\n\t\tfallthrough\n\n\tcase reflect.Struct:\n\t\tmethods := make(map[string]*funcx.Fn)\n\t\tannotations := make(map[string][]byte)\n\t\taf := reflect.Indirect(val).FieldByName(\"Annotations\")\n\t\tif af.IsValid() {\n\t\t\ta, ok := af.Interface().(map[string][]byte)\n\t\t\tif ok {\n\t\t\t\tannotations = a\n\t\t\t}\n\t\t}\n\t\tif methodsFuncs, ok := reflectx.WrapMethods(fn); ok {\n\t\t\tfor name, mfn := range methodsFuncs {\n\t\t\t\tf, err := funcx.New(mfn)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, errors.Wrapf(err, \"method %v invalid\", name)\n\t\t\t\t}\n\t\t\t\tmethods[name] = f\n\t\t\t}\n\t\t}\n\t\tfor mName := range lifecycleMethods {\n\t\t\tif _, ok := methods[mName]; ok {\n\t\t\t\tcontinue // skip : already wrapped\n\t\t\t}\n\t\t\tm, ok := val.Type().MethodByName(mName)\n\t\t\tif !ok {\n\t\t\t\tcontinue // skip: doesn't exist\n\t\t\t}\n\n\t\t\t// CAVEAT(herohde) 5/22/2017: The type val.Type.Method.Type is not\n\t\t\t// the same as val.Method.Type: the former has the explicit receiver.\n\t\t\t// We'll use the receiver-less version.\n\t\t\tf, err := funcx.New(reflectx.MakeFunc(val.Method(m.Index).Interface()))\n\t\t\tif err != nil {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L105-L141","documentation":"When NewFn constructs an Fn from a struct or interface, it wraps the type's lifecycle methods via reflectx.WrapMethods and builds each into a funcx.New callable. If any method's signature cannot be converted into a valid beam function (e.g., wrong parameter or return types), the error from funcx.New is wrapped as \"method %v invalid\". This surfaces at fn-registration time, before any element is processed.","triggerScenarios":"Defining a DoFn/CombineFn method (e.g., ProcessElement, CreateAccumulator, AddInput, MergeAccumulators, Setup, Teardown) with a signature funcx cannot bind — wrong argument kinds, unsupported return values, or missing required outputs.","commonSituations":"CombineFns where MergeAccumulators lacks the required accumulator return; ProcessElement with an unsupported iterator/emitter misuse; renaming/mis-signing lifecycle methods after an SDK upgrade; typos in method parameters like the emit function type.","solutions":["Read the wrapped inner error to see which signature rule the named method violates.","Fix the method signature to match beam requirements (e.g., MergeAccumulators(acc A) A; ProcessElement with valid ctx/input/emit/iterator params).","Compare against a working example DoFn/CombineFn in the beam Go SDK and mirror its parameter and return forms.","After an SDK version change, re-check lifecycle method signatures against the new funcx validation rules."],"exampleFix":"// before\nfunc (fn *myFn) ProcessElement(x int, y string) {} // unbindable: extra plain param without matching input\n// after\nfunc (fn *myFn) ProcessElement(x int) string { return strconv.Itoa(x) }","handlingStrategy":"validation","validationCode":"// Go: smoke-test the DoFn signature at startup before building pipelines\nif _, err := graph.NewDoFn(&myDoFn{}); err != nil {\n    log.Fatalf(\"invalid DoFn signature: %v\", err)\n}","typeGuard":"func validDoFn(fn interface{}) error {\n    _, err := graph.NewDoFn(fn)\n    return err\n}","tryCatchPattern":"// Go: wrap NewFn/NewDoFn errors with method context\nif _, err := graph.NewDoFn(myFn); err != nil {\n    return fmt.Errorf(\"DoFn %T rejected (check lifecycle method signatures): %w\", myFn, err)\n}","preventionTips":["Mirror canonical ProcessElement/MergeAccumulators signatures from SDK examples.","Validate DoFn/CombineFn signatures in unit tests so bad methods fail at build/CI time.","Re-check lifecycle method signatures after upgrading the Beam Go SDK.","Keep the unwrapped funcx error (errors.Unwrap) to identify the offending parameter or return type."],"tags":["beam-go","reflection","method-signature","dofn"],"backgroundTag":"invalid-argument-format","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"}