{"record":{"id":"c615ddd0763b89af","repo":"apache/beam","slug":"cannot-access-window-in-non-window-observing-context","errorCode":null,"errorMessage":"Cannot access window in non-window observing context.","messagePattern":"Cannot access window in non-window observing context\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java","lineNumber":1966,"sourceCode":"    }\n\n    @Override\n    public CausedByDrain causedByDrain() {\n      return currentElement.causedByDrain();\n    }\n\n    @Override\n    public CausedByDrain causedByDrain(DoFn<InputT, OutputT> doFn) {\n      return currentElement.causedByDrain();\n    }\n  }\n\n  /** Provides base arguments for a {@link DoFnInvoker} for a non-window observing method. */\n  private abstract class NonWindowObservingProcessBundleContextBase\n      extends ProcessBundleContextBase {\n    @Override\n    public BoundedWindow window() {\n      throw new UnsupportedOperationException(\n          \"Cannot access window in non-window observing context.\");\n    }\n\n    @Override\n    public Object sideInput(String tagId) {\n      throw new UnsupportedOperationException(\n          \"Cannot access sideInput in non-window observing context.\");\n    }\n\n    @Override\n    public <T> T sideInput(PCollectionView<T> view) {\n      throw new UnsupportedOperationException(\n          \"Cannot access sideInput in non-window observing context.\");\n    }\n\n    @Override\n    public State state(String stateId, boolean alwaysFetched) {\n      throw new UnsupportedOperationException(","sourceCodeStart":1948,"sourceCodeEnd":1984,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java#L1948-L1984","documentation":"The FnApiDoFnRunner's NonWindowObservingProcessBundleContextBase.window() throws UnsupportedOperationException because the current DoFn method was not declared window-observing (@ProcessElement with a BoundedWindow parameter), so no window is bound at invocation time. Calling c.window() from such a context is a programming error: the window argument simply is not available there.","triggerScenarios":"Calling ProcessContext.window() from a @ProcessElement method whose signature lacks a BoundedWindow parameter, or from a @StartBundle/@FinishBundle method, when the runner supplies the non-window-observing invoker context.","commonSituations":"Developers upgrading a DoFn and adding window() calls without changing the method signature; copy-pasting windowed logic into a non-windowed DoFn; accessing window in StartBundle/FinishBundle cleanup code.","solutions":["Add a BoundedWindow parameter to the @ProcessElement method signature so Beam makes it window-observing, then use that parameter instead of context.window().","If you need the window in bundle lifecycle methods, restructure to capture per-element windows in @ProcessElement and store them in state or an accumulator.","Confirm the DoFn does not run with a context base that intentionally rejects window access (non-window-observing methods)."],"exampleFix":"// before\n@ProcessElement\npublic void processElement(ProcessContext c) {\n  BoundedWindow w = c.window(); // throws\n}\n\n// after\n@ProcessElement\npublic void processElement(ProcessContext c, BoundedWindow window) {\n  // use window directly\n}","handlingStrategy":"validation","validationCode":"// Ensure the @ProcessElement signature includes a BoundedWindow before calling c.window():\n// Check via reflection at startup:\nboolean windowObserving = Arrays.stream(dofn.getClass().getDeclaredMethods())\n    .filter(m -> m.isAnnotationPresent(ProcessElement.class))\n    .allMatch(m -> Arrays.stream(m.getParameterTypes()).anyMatch(BoundedWindow.class::isAssignableFrom));","typeGuard":"interface WindowAwareContext { BoundedWindow window(); }\nBoundedWindow safeWindow(DoFn.ProcessContext ctx) {\n  return ctx instanceof WindowAwareContext ? ((WindowAwareContext) ctx).window() : null;\n}","tryCatchPattern":"try {\n  BoundedWindow w = c.window();\n  useWindow(w);\n} catch (UnsupportedOperationException e) {\n  // not a window-observing context; add BoundedWindow param to @ProcessElement\n  throw new IllegalStateException(\"Add BoundedWindow parameter to @ProcessElement\", e);\n}","preventionTips":["Always add BoundedWindow as a parameter to @ProcessElement when windowed logic is needed.","Do not call window() from @StartBundle or @FinishBundle — no window is bound there.","Review DoFn signatures in code review for window/timer/state usage consistency."],"tags":["java","beam","apache-beam","windowing","dofn"],"backgroundTag":"unsupported-operation","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"}