apache/beam · error · ValueError

assign_context.window should not be None. This might be due

Error message

assign_context.window should not be None. This might be due to a DoFn returning a TimestampedValue.

What it means

The identity window-assigning WindowFn's assign() expects an AssignContext whose window is set; a None window raises ValueError hinting the cause is usually a DoFn returning a TimestampedValue, which strips/re-creates windowing info instead of preserving the window. This surfaces as a runtime failure during window reassignment.

Source

Thrown at sdks/python/apache_beam/transforms/util.py:1442

  Will raise an exception when used after DoFns that return TimestampedValue
  elements.
  """
  def __init__(self, window_coder):
    """Create a new WindowFn with compatible coder.
    To be applied to PCollections with windows that are compatible with the
    given coder.

    Arguments:
      window_coder: coders.Coder object to be used on windows.
    """
    super().__init__()
    if window_coder is None:
      raise ValueError('window_coder should not be None')
    self._window_coder = window_coder

  def assign(self, assign_context):
    if assign_context.window is None:
      raise ValueError(
          'assign_context.window should not be None. '
          'This might be due to a DoFn returning a TimestampedValue.')
    return [assign_context.window]

  def get_window_coder(self):
    return self._window_coder


def reify_metadata_default_window(
    element, timestamp=DoFn.TimestampParam, pane_info=DoFn.PaneInfoParam):
  key, value = element
  if timestamp == window.MIN_TIMESTAMP:
    timestamp = None
  return key, (value, timestamp, pane_info)


def restore_metadata_default_window(element):
  key, values = element

View on GitHub (pinned to 12126d8942)

Solutions

  1. Emit elements with windows instead: return beam.window.TimestampedValue within a window-preserving DoFn, or use beam.WindowInto with an explicit WindowFn
  2. Use beam.pvalue.TaggedOutput with attributes, or attach timestamps via a Map before windowing so windows persist
  3. If using GroupIntoBatches/reassignment, emit plain values and let the WindowInto assign timestamps via context
  4. Restructure the DoFn to return windowed values, e.g. beam.window.WindowedValue(...) rather than TimestampedValue(...)

Example fix

// before
def process(self, element):
  yield beam.TimestampedValue(element, timestamp)
// after
def process(self, element, window=beam.DoFn.WindowParam, timestamp=beam.DoFn.TimestampParam):
  yield beam.window.WindowedValue(element, timestamp, [window])
Defensive patterns

Strategy: try-catch

Validate before calling

if isinstance(out, TimestampedValue):
    raise TypeError('DoFn must yield windowed values, not TimestampedValue')

Type guard

def is_windowed(v): return hasattr(v, 'windows') and v.windows

Try / catch

try:
    result = pcoll | util.GroupIntoBatches(...)
except ValueError as e:
    if 'assign_context.window' in str(e):
        fix_dofn_to_emit_windowed_values()

Prevention

When it happens

Trigger: A user DoFn emits beam.TimestampedValue(value, ts) while the pipeline applies window reassignment; the resulting element has no window object, so assign() gets assign_context.window=None and raises.

Common situations: Adding timestamps inside a DoFn via TimestampedValue under windowed/reassignment pipelines; mixing unwindowed and windowed PCollections; converting PCollection elements in ways that reset windows.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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