apache/beam · error
failed to find %v method
Error message
failed to find %v method
What it means
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.
Source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:503
// AsDoFn converts a Fn to a DoFn, if possible. numMainIn specifies how many
// main inputs are expected in the DoFn's method signatures. Valid inputs are
// the package constants of type mainInputs. If that number is MainUnknown then
// validation is done by best effort and may miss some edge cases.
func AsDoFn(fn *Fn, numMainIn mainInputs) (*DoFn, error) {
addContext := func(err error, fn *Fn) error {
return errors.WithContextf(err, "graph.AsDoFn: for Fn named %v", fn.Name())
}
if fn.methods == nil {
fn.methods = make(map[string]*funcx.Fn)
}
if fn.Fn != nil {
fn.methods[processElementName] = fn.Fn
}
if _, ok := fn.methods[processElementName]; !ok {
err := errors.Errorf("failed to find %v method", processElementName)
if fn.Recv != nil {
v := reflect.ValueOf(fn.Recv)
if v.Kind() != reflect.Ptr {
err = errors.Wrap(err, "structural DoFn passed by value, ensure that the ProcessElement method has a value receiver or pass the DoFn by pointer")
}
}
return nil, addContext(err, fn)
}
// Make sure that all state entries have keys. If they don't set them to the struct field name.
if fn.Recv != nil {
v := reflect.Indirect(reflect.ValueOf(fn.Recv))
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.CanInterface() {
if ps, ok := f.Interface().(state.PipelineState); ok {
if ps.StateKey() == "" {
f.FieldByName("Key").SetString(v.Type().Field(i).Name)View on GitHub (pinned to 12126d8942)
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
Example fix
// before
beam.ParDo(s, myFn{}, in) // ProcessElement has pointer receiver
// after
beam.ParDo(s, &myFn{}, in) Defensive patterns
Strategy: validation
Validate before calling
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") } } Type guard
func hasProcessElement(fn any) bool {
t := reflect.TypeOf(fn)
if t == nil { return false }
_, ok := t.MethodByName("ProcessElement")
return ok
} Try / catch
dfn, err := graph.NewDoFn(fn)
if err != nil && strings.Contains(err.Error(), "failed to find ProcessElement") {
return fmt.Errorf("%T lacks reachable ProcessElement; pass by pointer or add the method", fn)
} Prevention
- Define ProcessElement on every structural DoFn
- Pass DoFns by pointer so pointer-receiver methods are visible to reflection
When it happens
Trigger: Calling NewDoFn/AsDoFn on a structural DoFn (no ProcessElement method defined) or on a struct passed by value whose ProcessElement has a pointer receiver.
Common situations: Defining ProcessElement with a pointer receiver but passing the struct by value into beam.ParDo; forgetting ProcessElement entirely on a struct-based DoFn.
Related errors
- ProcessElement uses a StateProvider, but no State structs ar
- Unable to infer the types of StartBundle
- may only have a single context.Context parameter and it must
- may only have a single PaneInfo parameter and it must preced
- may only have a single Window parameter and it must precede
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a1562602b32e510a.
Report an issue: GitHub.