apache/beam · error · UnsupportedOperationException

RecordId unsupported in %s

Error message

RecordId unsupported in %s

What it means

DoFnInvoker's default UnsupportedInvocationBehavior throws this when a DoFn callback calls currentRecordOffset() in a context where the invocation behavior does not support it. Record/offset access is only meaningful for splittable-DoFn element+restriction processing; runners or invocation contexts that don't supply bundle data reject the call. It signals that the DoFn is asking for bundle metadata the current execution mode cannot provide.

Source

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

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

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

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

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

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

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the currentRecordOffset() call unless the DoFn is a genuine splittable DoFn (extends DoFn and is executed with the SDF expansion processElement+restriction)
  2. Test the DoFn with TestPipeline or DoFnTestUtils rather than invoking it directly with DoFnInvokers.invokerFor(...)
  3. Guard the accessor with a capability check (e.g. isBounded/Context information) and fall back to a no-op or logged skip when bundle data is unavailable
  4. Use an invoker whose InvocationBehavior supports bundle data (e.g. the runner's DoFnRunner) instead of the default UnsupportedInvocationBehavior

Example fix

// before
@ProcessElement
public void process(ProcessContext c, OffsetRangeTracker tracker) {
  long off = c.currentRecordOffset();
}
// after
@ProcessElement
public void process(ProcessContext c) {
  // use the element itself, not bundle metadata
  T value = c.element();
}
Defensive patterns

Strategy: validation

Validate before calling

// Before invoking the DoFn, ensure it is a splittable DoFn with bundle-data support,
// or invoke it through a runner-backed DoFnRunner rather than the default invoker:
if (!isSplittableDoFn(myDoFn)) {
  throw new IllegalStateException("DoFn uses currentRecordOffset but is not a splittable DoFn");
}

Type guard

boolean supportsBundleData(DoFnInvoker.BundlingContext ctx) {
  return ctx != null && !ctx.getClass().getSimpleName().equals("UnsupportedInvocationBehavior");
}

Try / catch

try {
  long offset = context.currentRecordOffset();
} catch (UnsupportedOperationException e) {
  // bundle data unavailable in this context; fall back
  LOG.warn("currentRecordOffset unsupported here: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling context.currentRecordOffset() (via a DoFnParameter or onBundleStart/Finish callbacks) when the DoFn is invoked with UnsupportedInvocationBehavior — e.g. via DoFnInvokers.tryInvokeSetUpProcessElementAndFinishBundle or a runner path that uses ProcessContext with no bundle data, or invoking a splittable-DoFn-only accessor from a non-DoFn runner context.

Common situations: Running a DoFn that uses splittable-DoFn bundle-data accessors (currentRecord, currentElement with restriction, currentRecordOffset) on a runner or test harness that does not provide bundle data; unit-testing such a DoFn with a plain invoker instead of DoFnTestUtils/TestPipeline; calling offset accessors outside onWindowExpiration or timer callbacks where they are unsupported.

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