apache/beam · error
OnTimer function not defined for DoFn: %v. Ensure that OnTim
Error message
OnTimer function not defined for DoFn: %v. Ensure that OnTimer function is implemented for the DoFn.
What it means
Beam Go requires any DoFn participating in timers to implement an OnTimer method. When validation detects a DoFn set up for timers (or pipeline validation reaches the timer check) but fn.methods has no entry for onTimerName, this error is thrown: callbacks fired by timers have nowhere to be dispatched.
Source
Thrown at sdks/go/pkg/beam/core/graph/fn.go:1393
}
stateKeys[k] = s
}
} else {
if len(ps) > 0 {
err := errors.Errorf("ProcessElement doesn't use a StateProvider, but State structs are attached to "+
"the DoFn: %v", ps)
return errors.SetTopLevelMsgf(err, "ProcessElement doesn't use a StateProvider, but State structs are "+
"attached to the DoFn: %v\nEnsure that you are using the StateProvider to perform any reads or writes"+
"of pipeline state.", ps)
}
}
return nil
}
func validateOnTimerFn(fn *DoFn) error {
if _, ok := fn.methods[onTimerName]; !ok {
err := errors.Errorf("OnTimer function not defined for DoFn: %v", fn.Name())
return errors.SetTopLevelMsgf(err, "OnTimer function not defined for DoFn: %v. Ensure that OnTimer function is implemented for the DoFn.", fn.Name())
}
pipelineTimers, _ := fn.PipelineTimers()
if _, ok := fn.methods[onTimerName].TimerProvider(); !ok {
err := errors.Errorf("OnTimer function doesn't use a TimerProvider, but Timer field is attached to the DoFn(%v): %v", fn.Name(), pipelineTimers)
return errors.SetTopLevelMsgf(err, "OnTimer function doesn't use a TimerProvider, but Timer field is attached to the DoFn(%v): %v"+
", Ensure that you are using the TimerProvider to set and clear the timers.", fn.Name(), pipelineTimers)
}
_, otNum, otExists := fn.methods[onTimerName].Emits()
_, peNum, peExists := fn.methods[processElementName].Emits()
if otExists == peExists {
if otNum != peNum {
return fmt.Errorf("OnTimer and ProcessElement functions for DoFn should have exactly same emitters, no. of emitters used in OnTimer: %v, no. of emitters used in ProcessElement: %v", otNum, peNum)
}View on GitHub (pinned to 12126d8942)
Solutions
- Implement the OnTimer method on the DoFn with the correct signature (context, timer.Set/OnTimer callback args).
- Match the timer IDs set via the TimerProvider with the ones handled in OnTimer.
- Refer to Beam's timer example DoFn and copy the complete pair (ProcessElement + OnTimer).
Example fix
// before
type BatchFn struct{ T timer.Provider }
func (fn *BatchFn) ProcessElement(ctx context.Context, tp timer.Provider, k beam.KV[string, string]) error {
tp.Set(...) // timers set, no OnTimer defined
}
// after
func (fn *BatchFn) OnTimer(ctx context.Context, ts timer.Signals, k beam.KV[string, string]) error {
// handle expiry
} Defensive patterns
Strategy: validation
Validate before calling
var _ interface {
OnTimer(context.Context, timer.Signals, beam.KV[string, string]) error
} = (*BatchFn)(nil) // compile-time check that OnTimer is implemented Type guard
func implementsOnTimer(fn interface{}) bool {
_, ok := fn.(interface{ OnTimer(context.Context, timer.Signals) error })
return ok
} Try / catch
if err := beam.Run(ctx, p); err != nil {
if strings.Contains(err.Error(), "OnTimer function not defined") {
log.Fatalf("implement OnTimer for %T: %v", dofn, err)
}
return err
} Prevention
- Always implement ProcessElement and OnTimer together when using timers
- Use a compile-time interface assertion for OnTimer on timer DoFns
- Copy complete DoFn examples, not fragments
When it happens
Trigger: Attaching Timer fields or a TimerProvider to a DoFn but not defining func (fn *X) OnTimer(ctx, ts, t) ...; implementing ProcessElement with timer logic and forgetting the OnTimer callback.
Common situations: Setting event-time timers in ProcessElement without defining the handler; copying only the ProcessElement half of a timer example; renames/refactors dropping the OnTimer method.
Related errors
- OnTimer function is defined for the DoFn but no TimerProvide
- OnTimer and ProcessElement functions for DoFn should have ex
- OnTimer and ProcessElement functions for DoFn should have ex
- OnTimer function doesn't use a TimerProvider, but Timer fiel
- ProcessElement uses a TimerProvider, but is not keyed. All s
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/3587d34bb9d44801.
Report an issue: GitHub.