apache/beam · error · IllegalStateException
Thread pool not initialized for UUID:
Error message
Thread pool not initialized for UUID:
What it means
getThreadPool looks up this DoFn instance's ExecutorService in a shared per-UUID map that is populated during @Setup. If the lookup returns null it throws IllegalStateException, meaning the wrapper is being used before setup ran or after teardown. This is an internal invariant: user code should never call it directly, so hitting it indicates a lifecycle misuse or runner bug.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/AsyncWrapper.java:220
? maxItemsToBuffer
: Math.max(parallelism * 2, DEFAULT_MIN_BUFFER_CAPACITY);
this.timeout = (timeout != null) ? timeout : Duration.standardSeconds(DEFAULT_TIMEOUT_SEC);
this.maxWaitTime =
(maxWaitTime != null) ? maxWaitTime : Duration.millis(DEFAULT_MAX_WAIT_TIME_MS);
this.idFn =
(idFn != null)
? idFn
: (SerializableFunction<InputT, Object>)
input -> java.util.Objects.requireNonNull(input);
this.useThreadPool = useThreadPool;
this.uuid = UUID.randomUUID().toString();
this.toProcessSpec = (coder != null) ? StateSpecs.bag(coder) : StateSpecs.bag();
}
private ExecutorService getThreadPool() {
ExecutorService threadPool = pool.get(uuid);
if (threadPool == null) {
throw new IllegalStateException("Thread pool not initialized for UUID: " + uuid);
}
return threadPool;
}
@SuppressWarnings("unchecked")
private ConcurrentHashMap<Object, InFlightElement<OutputT>> getProcessingElements() {
ConcurrentHashMap<Object, InFlightElement<?>> elements = processingElements.get(uuid);
if (elements == null) {
throw new IllegalStateException("Processing elements map not initialized for UUID: " + uuid);
}
return (ConcurrentHashMap<Object, InFlightElement<OutputT>>) (ConcurrentHashMap<?, ?>) elements;
}
private AtomicInteger getItemsInBuffer() {
AtomicInteger buffer = itemsInBuffer.get(uuid);
if (buffer == null) {
throw new IllegalStateException("Buffer counter not initialized for UUID: " + uuid);
}View on GitHub (pinned to 12126d8942)
Solutions
- Ensure the runner (or DoFnTester/DoFnInvokers.invokeSetup) invokes @Setup before any processElement calls
- In tests, run the DoFn through DoFnTester or TestPipeline rather than calling methods directly
- Verify the same DoFn instance that was set up is the one processing elements (no instance swapping)
Example fix
// before doFn.processElement(context); // direct call in test // after DoFnTester<InputT, OutputT> tester = DoFnTester.of(doFn); tester.processBundle(elements); // runs @Setup first
Defensive patterns
Strategy: try-catch
Validate before calling
// In tests: ensure setup before use DoFnInvokers.invokeSetupForTesting(doFn);
Try / catch
try {
doFn.processElement(ctx);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Thread pool not initialized")) {
DoFnInvokers.invokeSetupForTesting(doFn); // then retry
} else throw e;
} Prevention
- Always drive DoFns via DoFnTester or TestPipeline in unit tests
- Never invoke DoFn lifecycle methods manually on raw instances
- Keep a one-to-one mapping between setup/teardown and instance usage
When it happens
Trigger: Invoking the wrapped async function (via executor -> getThreadPool) when @Setup was not called, e.g. unit-testing the DoFn directly without running DoFnTester/setup, or calling after @Teardown.
Common situations: Hand-rolled test harnesses that call processElement without setup; runner lifecycle bugs or reuse of a torn-down DoFn instance.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Processing elements map not initialized for UUID:
- Buffer counter not initialized for UUID:
- Unexpected mode: " + mode
- Unknown mode: " + mode
- PipelineOptions not set
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2405f87f618d2c06.
Report an issue: GitHub.