{"record":{"id":"a1562602b32e510a","repo":"apache/beam","slug":"failed-to-find-v-method","errorCode":null,"errorMessage":"failed to find %v method","messagePattern":"failed to find (.+?) method","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/fn.go","lineNumber":503,"sourceCode":"\n// AsDoFn converts a Fn to a DoFn, if possible. numMainIn specifies how many\n// main inputs are expected in the DoFn's method signatures. Valid inputs are\n// the package constants of type mainInputs. If that number is MainUnknown then\n// validation is done by best effort and may miss some edge cases.\nfunc AsDoFn(fn *Fn, numMainIn mainInputs) (*DoFn, error) {\n\taddContext := func(err error, fn *Fn) error {\n\t\treturn errors.WithContextf(err, \"graph.AsDoFn: for Fn named %v\", fn.Name())\n\t}\n\n\tif fn.methods == nil {\n\t\tfn.methods = make(map[string]*funcx.Fn)\n\t}\n\tif fn.Fn != nil {\n\t\tfn.methods[processElementName] = fn.Fn\n\t}\n\n\tif _, ok := fn.methods[processElementName]; !ok {\n\t\terr := errors.Errorf(\"failed to find %v method\", processElementName)\n\t\tif fn.Recv != nil {\n\t\t\tv := reflect.ValueOf(fn.Recv)\n\t\t\tif v.Kind() != reflect.Ptr {\n\t\t\t\terr = errors.Wrap(err, \"structural DoFn passed by value, ensure that the ProcessElement method has a value receiver or pass the DoFn by pointer\")\n\t\t\t}\n\t\t}\n\t\treturn nil, addContext(err, fn)\n\t}\n\n\t// Make sure that all state entries have keys. If they don't set them to the struct field name.\n\tif fn.Recv != nil {\n\t\tv := reflect.Indirect(reflect.ValueOf(fn.Recv))\n\t\tfor i := 0; i < v.NumField(); i++ {\n\t\t\tf := v.Field(i)\n\t\t\tif f.CanInterface() {\n\t\t\t\tif ps, ok := f.Interface().(state.PipelineState); ok {\n\t\t\t\t\tif ps.StateKey() == \"\" {\n\t\t\t\t\t\tf.FieldByName(\"Key\").SetString(v.Type().Field(i).Name)","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/fn.go#L485-L521","documentation":"AsDoFn requires the Fn's methods map to contain a ProcessElement method. When absent it reports \"failed to find ProcessElement method\". For non-pointer receivers this usually means reflection cannot see the method because the struct was passed by value.","triggerScenarios":"Calling NewDoFn/AsDoFn on a structural DoFn (no ProcessElement method defined) or on a struct passed by value whose ProcessElement has a pointer receiver.","commonSituations":"Defining ProcessElement with a pointer receiver but passing the struct by value into beam.ParDo; forgetting ProcessElement entirely on a struct-based DoFn.","solutions":["Ensure the DoFn defines a ProcessElement method","Pass the DoFn by pointer: beam.ParDo(s, &myFn{}, in)","Or change ProcessElement to a value receiver"],"exampleFix":"// before\nbeam.ParDo(s, myFn{}, in) // ProcessElement has pointer receiver\n// after\nbeam.ParDo(s, &myFn{}, in)","handlingStrategy":"validation","validationCode":"if reflect.ValueOf(fn).Kind() == reflect.Struct { _, ok := reflect.TypeOf(fn).MethodByName(\"ProcessElement\"); if !ok { return errors.New(\"no ProcessElement method in value's method set\") } }","typeGuard":"func hasProcessElement(fn any) bool {\n  t := reflect.TypeOf(fn)\n  if t == nil { return false }\n  _, ok := t.MethodByName(\"ProcessElement\")\n  return ok\n}","tryCatchPattern":"dfn, err := graph.NewDoFn(fn)\nif err != nil && strings.Contains(err.Error(), \"failed to find ProcessElement\") {\n    return fmt.Errorf(\"%T lacks reachable ProcessElement; pass by pointer or add the method\", fn)\n}","preventionTips":["Define ProcessElement on every structural DoFn","Pass DoFns by pointer so pointer-receiver methods are visible to reflection"],"tags":["go","apache-beam","dofn","reflection"],"backgroundTag":"method-not-implemented","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}