apache/beam · error · IllegalStateException
Value only available at runtime, but accessed from a…
Error message
Value only available at runtime, but accessed from a non-runtime context: <provider>
What it means
RuntimeValueProvider.get() reads the PipelineOptions captured at runtime execution time from an internal optionsMap keyed by optionsId. This IllegalStateException is thrown when get() is called outside the runtime worker context (no options registered), meaning the value is unavailable at the current point of the pipeline lifecycle.
Solutions
- Move the get() call into runtime code (DoFn.processElement/@Setup on the worker)
- Check isAccessible() before calling get() and handle the driver-side case (use defaultValue or serialize the provider instead)
- In tests, use the test utilities that install runtime options (e.g. TestValueProvider or call valueProvider.setTestOptions-like helpers)
Example fix
// before
LOG.info("value is " + provider.get()); // throws at graph-build time
// after
if (provider.isAccessible()) { LOG.info("value is " + provider.get()); }
else { LOG.info("value resolved at runtime"); } Defensive patterns
Strategy: type-guard
Validate before calling
if (!provider.isAccessible()) { /* not yet in runtime context: defer or use default */ } Type guard
boolean usableNow(RuntimeValueProvider<?> p) { return p.isAccessible(); } Try / catch
try { v = provider.get(); } catch (IllegalStateException e) { v = defaultValue; /* driver-side fallback */ } Prevention
- Never call get() during pipeline construction; use isAccessible() to check
- Read runtime options only inside DoFn methods or other worker-side code
- In tests, install test options so providers are accessible before asserting on values
When it happens
Trigger: Calling get() (directly or indirectly via toString()) on a RuntimeValueProvider during graph construction/driver-side code instead of inside a DoFn/worker where options have been bound.
Common situations: Logging a value provider at pipeline-build time, accessing a runtime option in a constructor or @Setup-adjacent driver code, or calling get() in a unit test without simulating runtime options.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Only a RuntimeValueProvider or a NestedValueProvider can…
- .get() not called from a runtime context
- Unable to load runtime value.
- A function must be provided to convert the input type into…
- A PValue contained in
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9c30e92843d986c4.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/options/ValueProvider.java:255
this.propertyName = propertyName;
this.klass = klass;
this.defaultValue = defaultValue;
this.optionsId = optionsId;
}
/**
* Once set, all {@code RuntimeValueProviders} will return {@code true} from {@code
* isAccessible()}. By default, the value is set when deserializing {@link PipelineOptions}.
*/
static void setRuntimeOptions(PipelineOptions runtimeOptions) {
optionsMap.put(runtimeOptions.getOptionsId(), runtimeOptions);
}
@Override
public T get() {
PipelineOptions options = optionsMap.get(optionsId);
if (options == null) {
throw new IllegalStateException(
"Value only available at runtime, but accessed from a non-runtime context: " + this);
}
try {
Method method = klass.getMethod(methodName);
PipelineOptions methodOptions = options.as(klass);
InvocationHandler handler = Proxy.getInvocationHandler(methodOptions);
@SuppressWarnings("unchecked")
ValueProvider<T> result = (ValueProvider<T>) handler.invoke(methodOptions, method, null);
// Two cases: If we have deserialized a new value from JSON, it will
// be wrapped in a StaticValueProvider, which we can provide here. If
// not, there was no JSON value, and we return the default, whether or
// not it is null.
if (result instanceof StaticValueProvider) {
return result.get();
}
return defaultValue;
} catch (OutOfMemoryError oom) {
throw oom;View on GitHub (pinned to 12126d8942)