{"record":{"id":"8c08ce5076e989a4","repo":"apache/beam","slug":"cannot-access-timer-in-non-window-observing-context","errorCode":null,"errorMessage":"Cannot access timer in non-window observing context.","messagePattern":"Cannot access timer 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":1990,"sourceCode":"      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(\n          \"Cannot access state in non-window observing context.\");\n    }\n\n    @Override\n    public org.apache.beam.sdk.state.Timer timer(String timerId) {\n      throw new UnsupportedOperationException(\n          \"Cannot access timer in non-window observing context.\");\n    }\n\n    @Override\n    public TimerMap timerFamily(String timerFamilyId) {\n      throw new UnsupportedOperationException(\n          \"Cannot access timerFamily in non-window observing context.\");\n    }\n  }\n\n  /** Base implementation that does not override methods which need to be window aware. */\n  private abstract class ProcessBundleContextBase extends DoFn<InputT, OutputT>.ProcessContext\n      implements DoFnInvoker.ArgumentProvider<InputT, OutputT>, OutputReceiver<OutputT> {\n\n    private ProcessBundleContextBase() {\n      doFn.super();\n    }\n","sourceCodeStart":1972,"sourceCodeEnd":2008,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java#L1972-L2008","documentation":"NonWindowObservingProcessBundleContextBase.timer(String) throws UnsupportedOperationException because timers are defined per (key, window); in a non-window-observing context there is no window and thus no timer to create. The harness intentionally rejects timer creation here.","triggerScenarios":"Calling c.timer(timerId) from a @ProcessElement method lacking a BoundedWindow parameter, or from @StartBundle/@FinishBundle methods.","commonSituations":"Adding event-time timers to a DoFn without adding the BoundedWindow parameter; trying to set timers during bundle start/finish; copying timer code from a windowed DoFn into a plain one.","solutions":["Add a BoundedWindow parameter to the @ProcessElement method so the timer-capable (window-observing) context is used.","Set timers only from @ProcessElement on keyed collections; declare the timer with @TimerId and @TimerFamily annotations.","If you need time-based work without windowing, consider using a GlobalWindow with window-observing signature or restructure processing."],"exampleFix":"// before\n@ProcessElement\npublic void processElement(ProcessContext c) {\n  c.timer(myTimerId).set(c.timestamp().plus(Duration.standardMinutes(1))); // throws\n}\n\n// after\n@ProcessElement\npublic void processElement(ProcessContext c, BoundedWindow window) {\n  c.timer(myTimerId).set(c.timestamp().plus(Duration.standardMinutes(1)));\n}","handlingStrategy":"validation","validationCode":"// Timer creation requires window-observing @ProcessElement:\nboolean timerReady = Arrays.stream(dofn.getClass().getDeclaredMethods())\n    .filter(m -> m.isAnnotationPresent(ProcessElement.class))\n    .allMatch(m -> Arrays.asList(m.getParameterTypes()).contains(BoundedWindow.class));","typeGuard":"boolean canSetTimers(DoFn<?> doFn) {\n  return Arrays.stream(doFn.getClass().getDeclaredMethods())\n      .filter(m -> m.isAnnotationPresent(ProcessElement.class))\n      .anyMatch(m -> Arrays.asList(m.getParameterTypes()).contains(BoundedWindow.class));\n}","tryCatchPattern":"try {\n  c.timer(myTimerId).set(target);\n} catch (UnsupportedOperationException e) {\n  throw new IllegalStateException(\"timer() requires a window-observing @ProcessElement; add BoundedWindow param\", e);\n}","preventionTips":["Add BoundedWindow to @ProcessElement whenever @TimerId timers are used.","Set timers only from @ProcessElement on keyed PCollections.","Annotate timers with @TimerId on the DoFn and reference them as fields."],"tags":["java","beam","apache-beam","timers","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"}