{"record":{"id":"1500c23fc7076c10","repo":"apache/beam","slug":"timer-unsupported-in-s","errorCode":null,"errorMessage":"Timer unsupported in %s","messagePattern":"Timer unsupported in (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java","lineNumber":470,"sourceCode":"      throw new UnsupportedOperationException(\n          String.format(\"OnWindowExpirationContext unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public State state(String stateId, boolean alwaysFetched) {\n      throw new UnsupportedOperationException(\n          String.format(\"State unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public Timer timer(String timerId) {\n      throw new UnsupportedOperationException(\n          String.format(\"Timer unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public RestrictionTracker<?, ?> restrictionTracker() {\n      throw new UnsupportedOperationException(\n          String.format(\"RestrictionTracker unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public Object watermarkEstimatorState() {\n      throw new UnsupportedOperationException(\n          String.format(\"WatermarkEstimatorState unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public WatermarkEstimator<?> watermarkEstimator() {\n      throw new UnsupportedOperationException(\n          String.format(\"WatermarkEstimator unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public BundleFinalizer bundleFinalizer() {\n      throw new UnsupportedOperationException(","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java#L452-L488","documentation":"Requesting a Timer object from the stub DoFnInvoker implementation throws UnsupportedOperationException. Timers require a runner-backed context, which the base class never supplies. getErrorContext() names the DoFn and call context.","triggerScenarios":"Calling timer(timerId) on an invoker that does not override it — i.e. a placeholder invoker rather than one produced by DoFnInvokers.","commonSituations":"Using @TimerId with a runner lacking timer support; unit-test invokers built from the abstract base; accessing timers outside the appropriate lifecycle phase.","solutions":["Construct the invoker via DoFnInvokers.newInvoker/tryInvokeFor","Only request Timer inside lifecycle methods whose signature includes the timer parameter","Confirm the runner supports timers for this pipeline"],"exampleFix":"// before\nnew DoFnInvoker.BaseDoFnInvoker<T, O>(){}.timer(\"myTimer\"); // throws\n// after\nDoFnInvokers.tryInvokeFor(fn).timer(\"myTimer\");","handlingStrategy":"validation","validationCode":"if (signature.getTimerDeclarations().containsKey(timerId)) {\n  ensureInvokerSupportsTimers(invoker);\n}","typeGuard":"boolean supportsTimers(DoFnInvoker<?, ?> i) {\n  return !(i instanceof DoFnInvoker.BaseDoFnInvoker);\n}","tryCatchPattern":"try {\n  Timer timer = invoker.timer(timerId);\n} catch (UnsupportedOperationException e) {\n  throw new IllegalStateException(\"Timer unsupported for this invoker\", e);\n}","preventionTips":["Set timers via the @TimerId parameter inside lifecycle methods, not the invoker directly","Check runner timer support before pipeline submission","Use DoFnInvokers-built invokers in tests"],"tags":["java","apache-beam","unsupported-operation","timers"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}