apache/beam · error · Error

Unsupported non-merging WindowFn

Error message

Unsupported non-merging WindowFn: ${windowingStrategy}

What it means

CombinePerKeyPrecombineOperator.checkSupportsWindowing guards the precombine optimization: it only works when the windowing strategy's mergeStatus is NON_MERGING, but the supplied strategy requires merging windows (e.g. sessions). The windowingStrategy input is at fault — combining pre-window-merge is not implemented in this operator.

Solutions

  1. Use fixed or global windows instead of a merging WindowFn such as sessions.
  2. Fall back to a regular CombinePerKey without precombine so merging windows are handled after window merge.
  3. File an issue/patch to teach the precombine operator about merging window fns if you need sessions with precombine.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at sdks/typescript/src/apache_beam/worker/operators.ts:441 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/bb5c0518f261273e. Report an issue: GitHub.

Appendix: source

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

export class CombinePerKeyPrecombineOperator<I, A, O>
  extends CombineOperator<I, A, O>
  implements IOperator
{
  keyCoder: Coder<unknown>;
  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[

View on GitHub (pinned to 12126d8942)