apache/beam · error · UnsupportedOperationException

ValueKind unsupported in %s

Error message

ValueKind unsupported in %s

What it means

DoFnInvoker's UnsupportedInvocationBehavior throws this when a callback calls valueKind() in an invocation context that cannot report whether the current value is a plain element or a bundle-final element. valueKind() is a splittable-DoFn / specialized-runner concept; the default behavior has no kind to report and refuses the call. The message context names the DoFn and callback that made the invalid request.

Source

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

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

    @Override
    public CausedByDrain causedByDrain(DoFn<InputT, OutputT> doFn) {
      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(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the valueKind() call unless you specifically depend on bundle-final element semantics and run on a supporting runner
  2. Default the kind when unavailable: catch UnsupportedOperationException and treat it as the ordinary-element kind
  3. Test the DoFn with TestPipeline / runner-backed DoFnRunner instead of the default invoker
  4. If ValueKind is essential, ensure the execution path uses a DoFnRunner implementation that supports it (e.g. SplittableDoFn paths)

Example fix

// before
ValueKind kind = context.valueKind();
// after
ValueKind kind;
try { kind = context.valueKind(); } catch (UnsupportedOperationException e) { kind = ValueKind.ELEMENT; }
Defensive patterns

Strategy: fallback

Validate before calling

// Only read valueKind() when running on a runner path that supports it;
// in ordinary DoFns treat every element as ValueKind.ELEMENT.

Type guard

DoFn.ValueKind safeValueKind(DoFn.ProcessContext ctx) {
  try { return ctx.valueKind(); }
  catch (UnsupportedOperationException e) { return DoFn.ValueKind.ELEMENT; }
}

Try / catch

try {
  DoFn.ValueKind kind = context.valueKind();
} catch (UnsupportedOperationException e) {
  DoFn.ValueKind kind = DoFn.ValueKind.ELEMENT; // assume ordinary element
}

Prevention

When it happens

Trigger: Calling context.valueKind() from @ProcessElement or timer callbacks when the DoFn is invoked with UnsupportedInvocationBehavior — e.g. via DoFnInvokers.invokerFor(...) in tests or on runners without ValueKind support.

Common situations: Writing DoFn code that references valueKind() but running it on a runner or test harness that never sets it; copying splittable-DoFn idioms into ordinary DoFns; custom runner implementations lacking this API.

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/1b979078c7d16c44. Report an issue: GitHub.