apache/beam · error · UnsupportedOperationException
ProcessContext unsupported in
Error message
ProcessContext unsupported in ${context} What it means
DoFnInvoker.BaseArgumentProvider provides a default ArgumentProvider whose processContext() always throws UnsupportedOperationException. The Beam pipeline machinery substitutes a real, context-aware ArgumentProvider when a method actually needs a ProcessContext; hitting this default means the surrounding context does not support ProcessContext access.
Solutions
- Check where the DoFn method is being invoked: access ProcessContext only from @ProcessElement methods
- In tests, provide a stub ArgumentProvider that overrides processContext() instead of using BaseArgumentProvider defaults
- Use DoFnInvokers.invokerForFn() / the generated invoker so Beam installs the correct ArgumentProvider
- If you own the runner/integration code, pass an ArgumentProvider that implements processContext()
Example fix
// before (test stub)
new DoFnInvoker.BaseArgumentProvider<String, String>() {};
// after
new DoFnInvoker.BaseArgumentProvider<String, String>() {
@Override
public DoFn<String, String>.ProcessContext processContext(DoFn<String, String> doFn) {
return fakeProcessContext; // supplied by the test harness
}
}; Defensive patterns
Strategy: type-guard
Validate before calling
// Only access ProcessContext from @ProcessElement methods:
boolean inProcessElement = method.isAnnotationPresent(org.apache.beam.sdk.transforms.DoFn.ProcessElement.class);
if (!inProcessElement) {
throw new IllegalStateException("ProcessContext is only available in @ProcessElement");
} Type guard
static boolean hasProcessContext(DoFnInvoker.ArgumentProvider<?, ?> p) {
try { p.processContext(null); return true; }
catch (UnsupportedOperationException e) { return false; }
} Try / catch
try {
doFnInvoker.invokeProcessElement(args);
} catch (UnsupportedOperationException e) {
throw new IllegalStateException(
"ProcessContext unavailable here (" + e.getMessage() + "); move access into @ProcessElement", e);
} Prevention
- Access ProcessContext only inside @ProcessElement methods
- Use OnTimerContext/StartBundleContext types as declared by each callback
- In tests, stub processContext()/element() instead of using bare BaseArgumentProvider
- Prefer DoFnInvokers.invokerForFn() so Beam installs the correct provider
When it happens
Trigger: Calling doFn.processContext(...) (or invoking a method that requests a ProcessContext parameter) with the default BaseArgumentProvider that was not replaced — e.g. invoking a DoFn method in a context that is not a proper element-processing step, or tests calling methods directly with a plain invoker.
Common situations: Unit tests that construct a DoFnInvoker with the default BaseArgumentProvider and then call methods requiring a ProcessContext; calling a @ProcessElement-style method from @StartBundle/@FinishBundle where only bundle context is available; runner-side bugs invoking a DoFn with the wrong ArgumentProvider.
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
- Not expected to access Restriction from a regular DoFn in…
- Not expected to access RestrictionTracker from a regular…
- Cannot access fire timestamp outside of @OnTimer method.
- Cannot access key as parameter outside of @OnTimer method.
- Cannot access key as parameter outside of @OnTimer method.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/65c7671e49a96306.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java:306
*/
TimerMap timerFamily(String tagId);
/**
* Returns the timer id for the current timer of a {@link
* org.apache.beam.sdk.transforms.DoFn.TimerFamily}.
*/
String timerId(DoFn<InputT, OutputT> doFn);
}
/**
* This {@link ArgumentProvider} throws {@link UnsupportedOperationException} for all parameters.
*/
@Internal
abstract class BaseArgumentProvider<InputT, OutputT>
implements ArgumentProvider<InputT, OutputT> {
@Override
public DoFn<InputT, OutputT>.ProcessContext processContext(DoFn<InputT, OutputT> doFn) {
throw new UnsupportedOperationException(
String.format("ProcessContext unsupported in %s", getErrorContext()));
}
@Override
public InputT element(DoFn<InputT, OutputT> doFn) {
throw new UnsupportedOperationException(
String.format("Element unsupported in %s", getErrorContext()));
}
@Override
public @Nullable Object key() {
throw new UnsupportedOperationException(
"Cannot access key as parameter outside of @OnTimer method.");
}
@Override
public @Nullable Object sideInput(String tagId) {
throw new UnsupportedOperationException(View on GitHub (pinned to 12126d8942)