apache/beam · error · IllegalStateException
PipelineOptions not set
Error message
PipelineOptions not set
What it means
The FinishBundle-time argument provider exposes PipelineOptions to @FinishBundle methods; the options field is injected by the runner before invocation. If it is still null when pipelineOptions() is called, the wrapper throws IllegalStateException. This means the context object was used outside a runner-driven FinishBundle invocation.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/AsyncWrapper.java:401
BoundedWindow window,
Instant timestamp,
OutputReceiver<OutputT> receiver) {
return new ProcessArgProvider(element, window, timestamp, receiver);
}
// Named BaseArgumentProvider supplying bundle-level lifecycle context to the invoker.
private class BundleArgProvider extends DoFnInvoker.BaseArgumentProvider<InputT, OutputT> {
private final AccumulatingOutputReceiver<OutputT> receiver;
BundleArgProvider(AccumulatingOutputReceiver<OutputT> receiver) {
this.receiver = receiver;
}
@Override
public PipelineOptions pipelineOptions() {
PipelineOptions options = pipelineOptions;
if (options == null) {
throw new IllegalStateException("PipelineOptions not set");
}
return options;
}
@Override
public DoFn<InputT, OutputT>.FinishBundleContext finishBundleContext(
DoFn<InputT, OutputT> doFn) {
return new AsyncFinishBundleContext(doFn, receiver);
}
@Override
public String getErrorContext() {
return "AsyncWrapper/Bundle";
}
}
// FinishBundleContext subclass bound to the enclosing DoFn instance to prevent compiler crashes.
private class AsyncFinishBundleContext extends DoFn<InputT, OutputT>.FinishBundleContext {View on GitHub (pinned to 12126d8942)
Solutions
- Run the DoFn through a real runner or TestPipeline so options are injected before FinishBundle
- In tests, use DoFnTester with a context that provides PipelineOptions (e.g. PipelineOptionsFactory.create())
- If you own the invoker, call setPipelineOptions on the argument provider before invoking @FinishBundle
Example fix
// before customInvoker.invokeFinishBundle(provider); // provider has no options // after provider.setPipelineOptions(PipelineOptionsFactory.create()); customInvoker.invokeFinishBundle(provider);
Defensive patterns
Strategy: try-catch
Validate before calling
// Before invoking FinishBundle manually: options = PipelineOptionsFactory.create(); provider.setPipelineOptions(options);
Try / catch
try {
invoker.invokeFinishBundle(provider);
} catch (IllegalStateException e) {
if (e.getMessage().equals("PipelineOptions not set")) {
provider.setPipelineOptions(PipelineOptionsFactory.create());
invoker.invokeFinishBundle(provider);
} else throw e;
} Prevention
- Execute pipelines through a supported runner so options are injected automatically
- Inject PipelineOptionsFactory.create() in any custom test invokers
- Do not invoke @FinishBundle contexts outside the runner lifecycle
When it happens
Trigger: A @FinishBundle method (or code it calls) calls c.pipelineOptions() while the wrapper's pipelineOptions field was never populated — typically invoking the DoFn manually without a runner or without invoking setup with options.
Common situations: Unit tests that call finishBundle contexts directly; custom invokers that forget setPipelineOptions; runner integrations not passing options.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Property [%s] is marked with contradictory annotations. Foun
- All inherited interfaces of [%s] should inherit from the Pip
- Method [%s] has multiple definitions %s with different retur
- Interface [%s] has Methods with multiple definitions with di
- Expected getter for property [%s] to be marked with @%s on a
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/026c3d86e5ac648d.
Report an issue: GitHub.