apache/beam · error

error with side input

Error message

error with side input %d in DoFn %v: PCollections using merging WindowFns are not supported as side inputs. Consider re-windowing the side input PCollection before use

What it means

During pipeline construction, TryParDo validates side inputs. Beam Go does not support side inputs whose PCollection uses a merging WindowFn (e.g. Sessions), because windows would need to be materialized differently. When a side input's windowing strategy kind is window.Sessions, graph construction fails immediately with this error.

Solutions

  1. Re-window the side input PCollection into non-merging windows (window.FixedWindows or GlobalWindows) before using it as a side input, as the message suggests.
  2. Convert session results to GlobalWindows with a triggering/accumulation strategy if you need all session data per element.
  3. Restructure as a CoGBK / join instead of a side input if merging-window semantics are essential.
  4. Check for a shared helper that applies window.Sessions() and give the side-input branch its own windowing.

Example fix

// before
sessions := s | beam.WindowInto(window.NewSessions(10 * time.Minute))
out := main | beam.ParDo(dofn, beam.SideInput{Input: sessions}) // error

// after
fixed := s | beam.WindowInto(window.NewFixedWindows(10 * time.Minute))
out := main | beam.ParDo(dofn, beam.SideInput{Input: fixed})
Defensive patterns

Strategy: validation

Validate before calling

// Validate side inputs before building the DoFn:
func sideInputIsMerging(w window.Fn) bool {
    return w.Kind() == window.Sessions
}
if sideInputIsMerging(sessionsWfn) {
    sideInput = sideInput | beam.WindowInto(window.NewFixedWindows(10*time.Minute))
}

Type guard

func nonMergingSideInput(n *graph.Node) bool {
    return n.WindowingStrategy().Fn.Kind != window.Sessions
}

Prevention

When it happens

Trigger: Applying beam.ParDo (or any ParDo variant) with beam.SideInput where the side input PCollection was created with window.Sessions() (window.FixedWindows is fine). Fails at graph build time, before any data flows.

Common situations: Enriching a main collection with sessionized aggregates (e.g. joining per-session results as a side input); copying a side-input pattern from code where the side input was re-windowed into sessions for a different consumer.

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

Appendix: source

Thrown at sdks/go/pkg/beam/pardo.go:63

	doFnOpt := graph.NumMainInputs(graph.MainSingle)
	// Check the PCollection for any keyed type (not just KV specifically).
	if typex.IsKV(col.Type()) {
		doFnOpt = graph.NumMainInputs(graph.MainKv)
	} else if typex.IsCoGBK(col.Type()) {
		doFnOpt = graph.CoGBKMainInput(len(col.Type().Components()))
	}
	fn, err := graph.NewDoFn(dofn, doFnOpt)
	if err != nil {
		return nil, addParDoCtx(err, s)
	}

	in := []*graph.Node{col.n}
	inWfn := col.n.WindowingStrategy().Fn
	for i, s := range side {
		sideNode := s.Input.n
		sideWfn := sideNode.WindowingStrategy().Fn
		if sideWfn.Kind == window.Sessions {
			return nil, fmt.Errorf("error with side input %d in DoFn %v: PCollections using merging WindowFns are not supported as side inputs. Consider re-windowing the side input PCollection before use", i, fn)
		}
		if (inWfn.Kind == window.GlobalWindows) && (sideWfn.Kind != window.GlobalWindows) {
			return nil, fmt.Errorf("main input is global windowed in DoFn %v but side input %v is not, cannot map windows correctly. Consider re-windowing the side input PCollection before use", fn, i)
		}
		if (sideWfn.Kind == window.GlobalWindows) && !sideNode.Bounded() {
			// TODO(https://github.com/apache/beam/issues/21596): Replace this warning with an error return when proper streaming test functions have been added.
			log.Warnf(context.Background(), "side input %v is global windowed in DoFn %v but is unbounded, DoFn will block until end of Global Window. Consider windowing your unbounded side input PCollection before use. This will cause your pipeline to fail in a future release, see https://github.com/apache/beam/issues/21596 for details", i, fn)
		}
		in = append(in, s.Input.n)
	}

	var rc *coder.Coder
	// Sdfs will always encode restrictions as KV<restriction, watermark state | bool(false)>
	if fn.IsSplittable() {
		sdf := (*graph.SplittableDoFn)(fn)
		restT := typex.New(sdf.RestrictionT())
		// If no watermark estimator state, use boolean as a placeholder
		weT := typex.New(reflect.TypeOf(true))

View on GitHub (pinned to 12126d8942)