apache/beam · error
ProcessElement doesn't use a TimerProvider, but Timer field
Error message
ProcessElement doesn't use a TimerProvider, but Timer field is attached to the DoFn: %v, Ensure that you are using the TimerProvider to set and clear the timers.
What it means
A DoFn struct declares Timer fields, but its ProcessElement method does not accept a TimerProvider argument, so the SDK has no way to set or clear those timers. Beam requires that timers attached to a DoFn be driven through a TimerProvider in ProcessElement; fn.go raises this during graph validation.
Source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:1448
return errors.SetTopLevelMsgf(err, "ProcessElement uses a TimerProvider, but no timer fields are defined in the DoFn"+
", Ensure that your DoFn exports the Timer fields used to set and clear timers.")
}
timerKeys := make(map[string]string)
for i, t := range pt {
for timerFamilyID := range t.Timers() {
if timer, ok := timerKeys[timerFamilyID]; ok {
err := errors.Errorf("Duplicate timer key %v", timerFamilyID)
return errors.SetTopLevelMsgf(err, "Duplicate timer family ID %v used by struct fields %v and %v. Ensure that timer family IDs are unique per DoFn", timerFamilyID, timer, fieldNames[i])
}
timerKeys[timerFamilyID] = fieldNames[i]
}
}
if err := validateOnTimerFn(fn); err != nil {
return err
}
} else {
if len(pt) > 0 {
err := errors.Errorf("ProcessElement doesn't use a TimerProvider, but Timer field is attached to the DoFn: %v", pt)
return errors.SetTopLevelMsgf(err, "ProcessElement doesn't use a TimerProvider, but Timer field is attached to the DoFn: %v"+
", Ensure that you are using the TimerProvider to set and clear the timers.", pt)
}
if err := validateOnTimerFn(fn); err == nil {
actualErr := errors.New("OnTimer function is defined for the DoFn but no TimerProvider defined in ProcessElement")
return errors.SetTopLevelMsgf(actualErr, "OnTimer function is defined for the DoFn but no TimerProvider defined in ProcessElement."+
"Ensure that timers.Provider is defined in the ProcessElement and OnTimer methods of DoFn.")
}
}
return nil
}
// CombineFn represents a CombineFn.
type CombineFn Fn
// SetupFn returns the "Setup" function, if present.
func (f *CombineFn) SetupFn() *funcx.Fn {View on GitHub (pinned to 12126d8942)
Solutions
- Add a TimerProvider parameter to ProcessElement, e.g. `func (d *MyDoFn) ProcessElement(ctx context.Context, tp timers.Provider, elem T) ...` and use it to set/clear the Timer fields.
- Remove the Timer field (and any OnTimer method) if timers are no longer needed.
- Verify the Timer field is registered with a valid spec and that OnTimer wiring matches the provider usage.
- Check the Beam Go timer documentation for the current ProcessElement signature with TimerProvider.
Example fix
// before
func (d *MyDoFn) ProcessElement(ctx context.Context, elem string) { ... }
// after
func (d *MyDoFn) ProcessElement(ctx context.Context, tp timers.Provider, elem string) {
d.myTimer.Set(tp, deadline)
} Defensive patterns
Strategy: validation
Validate before calling
// ensure any DoFn with Timer fields also takes a timers.Provider in ProcessElement
func hasTimerProvider(fn interface{}) bool {
m := reflect.ValueOf(fn).MethodByName("ProcessElement")
t := m.Type()
for i := 0; i < t.NumIn(); i++ {
if t.In(i).Implements(reflect.TypeOf((*timers.Provider)(nil)).Elem()) { return true }
}
return false
} Prevention
- When adding a Timer field, update ProcessElement and OnTimer together.
- Follow current Beam Go timer examples; older APIs differ.
When it happens
Trigger: Declaring a `Timer` field on a DoFn whose ProcessElement signature is `ProcessElement(ctx, elem)` (no TimerProvider parameter), then constructing the pipeline.
Common situations: Adding a Timer field to an existing DoFn without updating ProcessElement; following older timer examples predating the TimerProvider API; stripping the TimerProvider parameter during refactoring while leaving the field.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- first main input parameter must be a value type
- too many return values: %v
- Duplicate timer family ID %v used by struct fields %v and %v
- ProcessElement uses a TimerProvider, but no Timer fields are
- bad parameter type for %s: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/99848e3d76c3eb5e.
Report an issue: GitHub.