apache/beam · error · IllegalArgumentException
Calling .triggering() to specify a trigger or calling .withA
Error message
Calling .triggering() to specify a trigger or calling .withAllowedLateness() to specify an allowed lateness greater than zero requires that the accumulation mode be specified using .discardingFiredPanes() or .accumulatingFiredPanes(). See Javadoc for more details.
What it means
When a windowing strategy can emit multiple panes per window (custom trigger or nonzero allowed lateness), Beam requires the accumulation mode to be stated explicitly. Window.applicableTo() throws IllegalArgumentException if the mode is unspecified, because the pipeline would otherwise be ambiguous about whether later panes accumulate or discard prior results.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java:368
private void applicableTo(PCollection<?> input) {
WindowingStrategy<?, ?> outputStrategy =
getOutputStrategyInternal(input.getWindowingStrategy());
// Make sure that the windowing strategy is complete & valid.
if (outputStrategy.isTriggerSpecified()
&& !(outputStrategy.getTrigger() instanceof DefaultTrigger)
&& !(outputStrategy.getWindowFn() instanceof GlobalWindows)
&& !outputStrategy.isAllowedLatenessSpecified()) {
throw new IllegalArgumentException(
"Except when using GlobalWindows,"
+ " calling .triggering() to specify a trigger requires that the allowed lateness"
+ " be specified using .withAllowedLateness() to set the upper bound on how late"
+ " data can arrive before being dropped. See Javadoc for more details.");
}
if (!outputStrategy.isModeSpecified() && canProduceMultiplePanes(outputStrategy)) {
throw new IllegalArgumentException(
"Calling .triggering() to specify a trigger or calling .withAllowedLateness() to"
+ " specify an allowed lateness greater than zero requires that the accumulation"
+ " mode be specified using .discardingFiredPanes() or .accumulatingFiredPanes()."
+ " See Javadoc for more details.");
}
}
private boolean canProduceMultiplePanes(WindowingStrategy<?, ?> strategy) {
// The default trigger is Repeatedly.forever(AfterWatermark.pastEndOfWindow()); This fires
// for every late-arriving element if allowed lateness is nonzero, and thus we must have
// an accumulating mode specified
boolean dataCanArriveLate =
!(strategy.getWindowFn() instanceof GlobalWindows)
&& strategy.getAllowedLateness().getMillis() > 0;
boolean hasCustomTrigger = !(strategy.getTrigger() instanceof DefaultTrigger);
return dataCanArriveLate || hasCustomTrigger;
}
View on GitHub (pinned to 12126d8942)
Solutions
- Append .discardingFiredPanes() if each pane should contain only the new elements since the last firing.
- Append .accumulatingFiredPanes() if each pane should contain all elements accumulated so far.
- Remove .triggering()/.withAllowedLateness() if single-panes-per-window is actually desired (DefaultTrigger with zero lateness needs no mode).
Example fix
// before
PCollection<T> out = items.apply(Window.<T>into(FixedWindows.of(StandardMinutes.of(1)))
.triggering(AfterWatermark.pastEndOfWindow())
.withAllowedLateness(StandardMinutes.of(1)));
// after
PCollection<T> out = items.apply(Window.<T>into(FixedWindows.of(StandardMinutes.of(1)))
.triggering(AfterWatermark.pastEndOfWindow())
.withAllowedLateness(StandardMinutes.of(1))
.accumulatingFiredPanes()); Defensive patterns
Strategy: validation
Validate before calling
if ((trigger != null && !(trigger instanceof DefaultTrigger)) || (allowedLateness != null && allowedLateness.isLongerThan(Duration.ZERO))) {
if (!discardingFiredPanes && !accumulatingFiredPanes) {
throw new IllegalArgumentException("specify .discardingFiredPanes() or .accumulatingFiredPanes()");
}
} Prevention
- Whenever you add a trigger or lateness, decide the accumulation mode at the same time.
- Prefer .accumulatingFiredPanes() for correctness-checked pipelines and .discardingFiredPanes() for efficiency, documenting the choice.
- Keep windowing configuration in one helper method so mode and trigger cannot drift apart.
When it happens
Trigger: Calling Window.into(fn).triggering(...) or .withAllowedLateness(greater than zero) without calling .discardingFiredPanes() or .accumulatingFiredPanes(), so canProduceMultiplePanes(strategy) is true and isModeSpecified() is false.
Common situations: Adding triggers or allowed lateness to an existing windowed pipeline but forgetting to pick an accumulation mode; upgrading Beam where stricter validation now catches previously silent ambiguity; following snippets that omitted the mode.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Except when using GlobalWindows, calling .triggering() to sp
- Inputs to Flatten had incompatible triggers: %s, %s
- Only %s objects with the same window supplier are compatible
- ApproximateUnique.PerKey needs an estimation error between 1
- ApproximateUnique.PerKey requires its input to use KvCoder
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b47f553788d73270.
Report an issue: GitHub.