apache/beam · error

Unsupported windowing output time: " + windowingStrategy

Error message

Unsupported windowing output time: " + windowingStrategy

What it means

After verifying the windowing strategy is non-merging, the direct runner also requires outputTime to be END_OF_WINDOW; any other output-time behavior is not implemented and throws. The runner stamps elements with the window end when emitting, so alternative output-time semantics cannot be honored.

Solutions

  1. Leave the windowing strategy at its default output time (END_OF_WINDOW).
  2. If building strategies manually, set outputTime: runnerApi.OutputTime_Enum.END_OF_WINDOW.
  3. Use a different runner if you need alternate output-time semantics.

Example fix

// before
windowingStrategy.outputTime = runnerApi.OutputTime_Enum.CUSTOM;
// after
windowingStrategy.outputTime = runnerApi.OutputTime_Enum.END_OF_WINDOW;
Defensive patterns

Strategy: validation

Validate before calling

if (windowingStrategy && windowingStrategy.outputTime !== undefined &&
    windowingStrategy.outputTime !== runnerApi.OutputTime_Enum.END_OF_WINDOW) {
  console.warn('Direct runner requires outputTime END_OF_WINDOW');
}

Prevention

When it happens

Trigger: A windowing strategy whose outputTime field is set to a value other than OutputTime_Enum.END_OF_WINDOW (e.g. END_OF_WINDOW_EXTRA or custom timestamp policies) while running on the direct runner.

Common situations: Constructing windowing strategies programmatically with custom output time; strategies produced by a newer SDK or another language binding with different output-time defaults; custom timestamp combinators.

Related errors


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

Appendix: source

Thrown at sdks/typescript/src/apache_beam/runners/direct_runner.ts:214

    );
    const inputPc =
      context.descriptor.pcollections[
        onlyElement(Object.values(transform.inputs))
      ];
    this.keyCoder = context.pipelineContext.getCoder(
      context.descriptor.coders[inputPc.coderId].componentCoderIds[0],
    );
    const windowingStrategy =
      context.descriptor.windowingStrategies[inputPc.windowingStrategyId];
    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,
      );
    }
    this.windowCoder = context.pipelineContext.getCoder(
      windowingStrategy.windowCoderId,
    );
  }

  process(wvalue: WindowedValue<any>) {
    for (const window of wvalue.windows) {
      const wkey =
        operators.encodeToBase64(window, this.windowCoder) +
        " " +
        operators.encodeToBase64(wvalue.value.key, this.keyCoder);
      if (!this.groups.has(wkey)) {
        this.groups.set(wkey, []);
      }
      this.groups.get(wkey)!.push(wvalue.value.value);

View on GitHub (pinned to 12126d8942)