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

  1. 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.
  2. Remove the Timer field (and any OnTimer method) if timers are no longer needed.
  3. Verify the Timer field is registered with a valid spec and that OnTimer wiring matches the provider usage.
  4. 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 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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/99848e3d76c3eb5e. Report an issue: GitHub.