apache/beam · error · RuntimeError

Sessions is not allowed in side inputs

Error message

Sessions is not allowed in side inputs

What it means

default_window_mapping_fn builds a WindowMappingFn that maps source windows to side-input windows. Session windowing is explicitly rejected because mapping an arbitrary source window into session windows is ill-defined (sessions depend on the data itself). The library raises RuntimeError instead of guessing a mapping.

Solutions

  1. Re-window the side-input PCollection to a supported windowing (GlobalWindows, FixedWindows, etc.) before passing it as a side input.
  2. Use a plain join/CoGroupByKey instead of a side input when both sides are session-windowed.
  3. Provide an explicit window_mapping_fn on the view (e.g. via a custom SideInputMap / default_window_selection_fn) rather than relying on the default mapping.

Example fix

// before
side = pcoll | 'sessions' >> beam.WindowInto(window.Sessions(600))
result = main | beam.Map(lambda x, s: ..., side=beam.pvalue.AsIter(side))
// after
side_fixed = side | beam.WindowInto(window.GlobalWindows())
result = main | beam.Map(lambda x, s: ..., side=beam.pvalue.AsIter(side_fixed))
Defensive patterns

Strategy: validation

Validate before calling

from apache_beam import window
if isinstance(side_pcoll.windowing.windowfn, window.Sessions):
    raise ValueError('Side input PCollection must not use Sessions windowing')

Type guard

def is_side_input_safe(pcoll) -> bool:
    from apache_beam import window
    fn = pcoll.windowing.windowfn
    return not isinstance(fn, window.Sessions)

Try / catch

try:
    result = main | beam.Map(fn, side=beam.pvalue.AsIter(side))
except RuntimeError as e:
    if 'Sessions is not allowed in side inputs' in str(e):
        side = side | beam.WindowInto(window.GlobalWindows())
        result = main | beam.Map(fn, side=beam.pvalue.AsIter(side))

Prevention

When it happens

Trigger: Using pvalue.AsIter(side_input) (or AsList/AsSingleton) on a PCollection windowed with window.Sessions() while the main collection uses a different windowing; default_window_mapping_fn is called with a Sessions instance and raises.

Common situations: Joining or enriching a sessionized stream with side inputs; users converting a DoFn to take side inputs after re-windowing data into sessions.

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

Appendix: source

Thrown at sdks/python/apache_beam/transforms/sideinputs.py:58

SIDE_INPUT_PREFIX = 'python_side_input'

SIDE_INPUT_REGEX = SIDE_INPUT_PREFIX + '([0-9]+)(-.*)?$'


# Top-level function so we can identify it later.
def _global_window_mapping_fn(
    w, global_window=window.GlobalWindow()) -> window.GlobalWindow:
  return global_window


def default_window_mapping_fn(
    target_window_fn: window.WindowFn) -> WindowMappingFn:
  if target_window_fn == window.GlobalWindows():
    return _global_window_mapping_fn

  if isinstance(target_window_fn, window.Sessions):
    raise RuntimeError("Sessions is not allowed in side inputs")

  def map_via_end(source_window: window.BoundedWindow) -> window.BoundedWindow:
    return list(
        target_window_fn.assign(
            window.WindowFn.AssignContext(
                source_window.max_timestamp(), window=source_window)))[-1]

  return map_via_end


def get_sideinput_index(tag: str) -> int:
  match = re.match(SIDE_INPUT_REGEX, tag, re.DOTALL)
  if match:
    return int(match.group(1))
  else:
    raise RuntimeError("Invalid tag %r" % tag)

View on GitHub (pinned to 12126d8942)