apache/beam · error · Error

Unsupported windowing output time

Error message

Unsupported windowing output time: ${windowingStrategy}

What it means

The second guard in checkSupportsWindowing: the operator requires outputTime == END_OF_WINDOW so timestamps assigned to combined outputs are deterministic, but the strategy uses another OutputTime_Enum (END_OF_TIMESTAMP or START_OF_WINDOW). The windowingStrategy's output time configuration is the input at fault.

Solutions

  1. Set the windowing strategy's output time to END_OF_WINDOW (e.g. Window.into(...).withOutputTimeFn(OutputTimeFns.endOfWindow())) or use default fixed windows.
  2. Avoid withAllowedLateness/custom timestamp policies that change output time when using precombine.
  3. If another output time is required, skip the precombine operator.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at sdks/typescript/src/apache_beam/worker/operators.ts:446 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at sdks/typescript/src/apache_beam/worker/operators.ts:446

  windowCoder: Coder<Window>;

  // Use a Map for LRU ordering: JavaScript Maps preserve insertion order,
  // so we can implement LRU by deleting and re-inserting on access.
  groups: Map<string, A>;
  maxKeys: number = 10000;

  static checkSupportsWindowing(
    windowingStrategy: runnerApi.WindowingStrategy,
  ) {
    if (
      windowingStrategy.mergeStatus !== runnerApi.MergeStatus_Enum.NON_MERGING
    ) {
      throw new Error("Unsupported non-merging WindowFn: " + windowingStrategy);
    }
    if (
      windowingStrategy.outputTime !== runnerApi.OutputTime_Enum.END_OF_WINDOW
    ) {
      throw new Error(
        "Unsupported windowing output time: " + windowingStrategy,
      );
    }
  }

  constructor(
    transformId: string,
    transform: PTransform,
    context: OperatorContext,
  ) {
    super(transformId, transform, context);
    const inputPc =
      context.descriptor.pcollections[
        onlyElement(Object.values(transform.inputs))
      ];
    this.keyCoder = context.pipelineContext.getCoder(
      context.descriptor.coders[inputPc.coderId].componentCoderIds[0],
    );

View on GitHub (pinned to 12126d8942)