apache/beam · error

OnTimer function doesn't use a TimerProvider, but Timer fiel

Error message

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.

What it means

This error fires when a DoFn defines Timer fields but its OnTimer method does not take a TimerProvider parameter. Beam's timers model requires timer access (setting/clearing) to flow through the TimerProvider; attached Timer fields that OnTimer never receives indicate dead or miswired configuration.

Source

Thrown at sdks/go/pkg/beam/core/graph/fn.go:1400

			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)
		}
	} else {
		return fmt.Errorf("OnTimer and ProcessElement functions for DoFn should have exactly same emitters, emitters used in OnTimer: %v, emitters used in ProcessElement: %v", otExists, peExists)
	}

	return nil
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Add the timer.Provider parameter to OnTimer (and ProcessElement where needed) and use it to set/clear timers.
  2. Remove the unused Timer fields if the DoFn no longer uses timers.
  3. Compare with a working Beam timer DoFn example and align all signatures.

Example fix

// before
func (fn *BatchFn) OnTimer(ctx context.Context, ts timer.Signals, k beam.KV[string, string]) error { ... }
// after
func (fn *BatchFn) OnTimer(ctx context.Context, tp timer.Provider, ts timer.Signals, k beam.KV[string, string]) error {
    tp.Set(...)
}
Defensive patterns

Strategy: validation

Validate before calling

// OnTimer must accept timer.Provider if Timer fields are declared
t := reflect.TypeOf(fn)
for i := 0; i < t.NumField(); i++ {
    if strings.Contains(fmt.Sprint(t.Field(i).Type), "timer.") {
        // verify method signature includes timer.Provider
        break
    }
}

Try / catch

if err := beam.Run(ctx, p); err != nil {
    if strings.Contains(err.Error(), "doesn't use a TimerProvider, but Timer field is attached") {
        log.Fatalf("add timer.Provider to OnTimer or remove unused Timer fields: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Declaring exported timer fields on the DoFn while OnTimer's signature lacks timer.Provider (or ProcessElement/OnTimer were refactored so the provider parameter was dropped).

Common situations: Removing the TimerProvider argument during a signature refactor while leaving the fields; copying only the fields from a timer example without the provider parameters; adding timers to an existing DoFn without updating OnTimer.

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/c4e6cd3f91dfef27. Report an issue: GitHub.