apache/beam · error · UnsupportedOperationException

TimerId unsupported in

Error message

TimerId unsupported in %s

What it means

DoFnInvoker's context-parameter base implementation throws UnsupportedOperationException for any context accessor the invoker does not support. Calling timerId() on an invoker that was not built with timer support raises "TimerId unsupported in %s" with an error context describing the invoker. It signals that the runner/decoration in use does not supply TimerId access, not a bug in user code per se.

Solutions

  1. Ensure the DoFn method accessing timerId() runs in a real timer callback context supplied by the runner
  2. When constructing the invoker manually, pass a timerIdFactory / use an invoker implementation that supports timers
  3. Wrap the timerId() call in a capability check or guard so it is only reached when the context actually supports timers
  4. Check runner documentation for timer support; use a runner/DoFnTester version that supports timers

Example fix

// before
String id = context.timerId();
// after
String id = (context instanceof DoFn.OnTimerContext) ? ((DoFn.OnTimerContext) context).timerId() : null;
Defensive patterns

Strategy: try-catch

Validate before calling

if (context instanceof DoFn.OnTimerContext) { /* safe to use timerId */ }

Type guard

boolean hasTimerSupport = context instanceof DoFn.OnTimerContext;

Try / catch

try { String id = context.timerId(); } catch (UnsupportedOperationException e) { /* fall back / log unsupported */ }

Prevention

When it happens

Trigger: A DelegatingDoFnInvoker (or generated invoker without a TimerId factory) whose timerId(DoFn) is invoked — typically when DoFn.ProcessElement/OnTimer code calls context.timerId() but the invoker was constructed without timer context support.

Common situations: Running a DoFn with timers on a runner or test harness that does not populate timer context; using a hand-built invoker (e.g. DoFnInvokers.newInvoker) without binding timerId; calling timerId() outside an @OnTimer callback.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/8610702971a9c5a2. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java:384

      throw new UnsupportedOperationException(
          String.format("CausedByDrain unsupported in %s", getErrorContext()));
    }

    @Override
    public ValueKind valueKind(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("ValueKind unsupported in %s", getErrorContext()));
    }

    @Override
    public String timerId(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("TimerId unsupported in %s", getErrorContext()));
    }

    @Override
    public TimeDomain timeDomain(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("TimeDomain unsupported in %s", getErrorContext()));
    }

    @Override
    public OutputReceiver<OutputT> outputReceiver(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("OutputReceiver unsupported in %s", getErrorContext()));
    }

    @Override
    public OutputReceiver<Row> outputRowReceiver(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("Row OutputReceiver unsupported in %s", getErrorContext()));
    }

    @Override
    public MultiOutputReceiver taggedOutputReceiver(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(

View on GitHub (pinned to 12126d8942)