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
- 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.
- Convert session results to GlobalWindows with a triggering/accumulation strategy if you need all session data per element.
- Restructure as a CoGBK / join instead of a side input if merging-window semantics are essential.
- 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
- Never use window.Sessions() outputs as side inputs; re-window to fixed/global first.
- Centralize windowing helpers so side-input branches get explicit non-merging windows.
- Prefer joins/CoGBK when merging-window semantics are truly needed.
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
- main input is global windowed in DoFn
- Attempted to get side input window for GlobalWindow from…
- Attempted to get side input window for GlobalWindow from…
- cannot make a keyed iterable for an unkeyed side input
- failed to map main input window to side input window with…
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)