apache/beam · error

Iterators with timestamp values (<ET,V> and <ET, K, V>) are

Error message

Iterators with timestamp values (<ET,V> and <ET, K, V>) are not valid, as side input time stamps are not preserved after windowing. See https://github.com/apache/beam/issues/22404 for more information.

What it means

Beam Go rejects side-input iterator signatures whose first parameter is an EventTime (a `<ET,...>` style signature). Side input timestamps are not preserved after windowing, so an event-time-carrying iterator would silently give wrong times; the SDK forbids it outright (errIllegalEventTimeInIter), referencing beam issue #22404.

Source

Thrown at sdks/go/pkg/beam/core/funcx/sideinput.go:84

	return types, ok
}

func unfoldIter(t reflect.Type) ([]reflect.Type, bool, error) {
	if t.Kind() != reflect.Func {
		return nil, false, nil
	}

	if t.NumOut() != 1 || t.Out(0) != reflectx.Bool {
		return nil, false, nil
	}
	if t.NumIn() == 0 {
		return nil, false, nil
	}

	var ret []reflect.Type
	skip := 0
	if t.In(0).Kind() == reflect.Ptr && t.In(0).Elem() == typex.EventTimeType {
		return nil, false, errors.New(errIllegalEventTimeInIter)
	}
	if t.NumIn()-skip > 2 || t.NumIn() == skip {
		return nil, false, nil
	}

	for i := skip; i < t.NumIn(); i++ {
		if ok, err := isOutParam(t.In(i)); !ok {
			return nil, false, errors.Wrap(err, errIllegalParametersInIter)
		}
		if reflect.TypeOf((*any)(nil)).Elem() == t.In(i).Elem() && !typex.IsUniversal(t.In(i)) {
			return nil, false, errors.New("Type interface{} isn't a supported PCollection type")
		}
		ret = append(ret, t.In(i).Elem())
	}
	return ret, true, nil
}

func isOutParam(t reflect.Type) (bool, error) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the EventTime parameter from the side-input iterator signature; iterate values only (e.g. `func(v V) bool`).
  2. If timestamps are needed, encode the timestamp into the value (KV<Timestamp,V>) before the side input is created.
  3. Use a main-input parameter for event time (main inputs preserve timestamps) rather than a side input.
  4. Track https://github.com/apache/beam/issues/22404 for possible future support.

Example fix

// before
func (fn *f) ProcessElement(s beamutil.SideInputIter func(typex.EventTime, string) bool) {}
// after
func (fn *f) ProcessElement(s beamutil.SideInputIter func(string) bool) {}
Defensive patterns

Strategy: validation

Validate before calling

func iterHasEventTimeFirst(fn reflect.Type) bool {
    if fn.NumIn() == 0 { return false }
    in0 := fn.In(0)
    return in0.Kind() == reflect.Ptr && in0.Elem() == reflect.TypeOf(typex.EventTime(0))
}

Type guard

func isEventTime(t reflect.Type) bool { return t == reflect.TypeOf(typex.EventTime(0)) }

Prevention

When it happens

Trigger: Declaring a DoFn ProcessElement whose side-input parameter is `func(reflect chan/iter ...)` with a leading `typex.EventTime` pointer parameter — e.g. `ProcessElement(et typex.EventTime, ...)` combined with an iterator `func(*func(et typex.EventTime, v T) bool)` produced when the first In(0) is a Ptr to EventTimeType.

Common situations: Developers porting Java/Python Beam `<ET,V>` side input patterns to Go, or expecting side input timestamps to survive GBK/windowing, then writing iterators with event-time first parameters.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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