{"record":{"id":"b11c223d2cf1b3ec","repo":"apache/beam","slug":"except-when-using-globalwindows-calling-triggering-to","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java","lineNumber":360,"sourceCode":"    if (getOnTimeBehavior() != null) {\n      result = result.withOnTimeBehavior(getOnTimeBehavior());\n    }\n    if (getTimestampCombiner() != null) {\n      result = result.withTimestampCombiner(getTimestampCombiner());\n    }\n    return result;\n  }\n\n  private void applicableTo(PCollection<?> input) {\n    WindowingStrategy<?, ?> outputStrategy =\n        getOutputStrategyInternal(input.getWindowingStrategy());\n\n    // Make sure that the windowing strategy is complete & valid.\n    if (outputStrategy.isTriggerSpecified()\n        && !(outputStrategy.getTrigger() instanceof DefaultTrigger)\n        && !(outputStrategy.getWindowFn() instanceof GlobalWindows)\n        && !outputStrategy.isAllowedLatenessSpecified()) {\n      throw new IllegalArgumentException(\n          \"Except when using GlobalWindows,\"\n              + \" calling .triggering() to specify a trigger requires that the allowed lateness\"\n              + \" be specified using .withAllowedLateness() to set the upper bound on how late\"\n              + \" data can arrive before being dropped. See Javadoc for more details.\");\n    }\n\n    if (!outputStrategy.isModeSpecified() && canProduceMultiplePanes(outputStrategy)) {\n      throw new IllegalArgumentException(\n          \"Calling .triggering() to specify a trigger or calling .withAllowedLateness() to\"\n              + \" specify an allowed lateness greater than zero requires that the accumulation\"\n              + \" mode be specified using .discardingFiredPanes() or .accumulatingFiredPanes().\"\n              + \" See Javadoc for more details.\");\n    }\n  }\n\n  private boolean canProduceMultiplePanes(WindowingStrategy<?, ?> strategy) {\n    // The default trigger is Repeatedly.forever(AfterWatermark.pastEndOfWindow()); This fires\n    // for every late-arriving element if allowed lateness is nonzero, and thus we must have","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/windowing/Window.java#L342-L378","documentation":"In Apache Beam, a WindowingStrategy is only complete if a non-default trigger on a non-global window also declares an allowed lateness bound. Window.applicableTo() validates this at pipeline-construction time and throws IllegalArgumentException because, without a lateness bound, the runner cannot know when late data should be dropped relative to the custom trigger's windows of firing. GlobalWindows are exempt since all data is implicitly on time.","triggerScenarios":"Calling Window.into(fn).triggering(AfterWatermark.pastEndOfWindow()) (or any trigger other than DefaultTrigger) with a non-GlobalWindows WindowFn and never calling .withAllowedLateness(...).","commonSituations":"Building time-based windowing pipelines with custom triggers (e.g. early firings via AfterWatermark or Repeatedly.forever) and forgetting the lateness setting; copying trigger code from examples that used GlobalWindows; refactors where .withAllowedLateness was dropped.","solutions":["Add .withAllowedLateness(Duration) (e.g. .withAllowedLateness(StandardMinutes.of(1))) after .triggering(...) on the Window transform.","If you truly need no lateness semantics, check whether GlobalWindows is the right WindowFn, which exempts you from this requirement.","If a custom trigger is unnecessary, remove .triggering(...) and use the DefaultTrigger, which requires no lateness."],"exampleFix":"// before\nPCollection<T> out = items.apply(Window.<T>into(FixedWindows.of(StandardMinutes.of(1)))\n    .triggering(AfterWatermark.pastEndOfWindow()));\n// after\nPCollection<T> out = items.apply(Window.<T>into(FixedWindows.of(StandardMinutes.of(1)))\n    .triggering(AfterWatermark.pastEndOfWindow())\n    .withAllowedLateness(StandardMinutes.of(1)));","handlingStrategy":"validation","validationCode":"if (windowFn instanceof GlobalWindows == false && trigger != null && !(trigger instanceof DefaultTrigger) && allowedLateness == null) {\n  throw new IllegalArgumentException(\"custom trigger requires withAllowedLateness(...)\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always chain .withAllowedLateness(...) immediately after .triggering(...) as a habit.","Use a project-standard builder helper that enforces the trigger+lateness pairing.","Review windowing code with a checklist: WindowFn, trigger, lateness, accumulation mode."],"tags":["java","apache-beam","windowing","triggers","pipeline-construction"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}