junit-team/junit5 · error · IllegalStateException
Not on a worker thread
Error message
Not on a worker thread
What it means
Thrown by WorkerThread.getOrThrow() (line 274-280) as an IllegalStateException when Thread.currentThread() is not a WorkerThread of this executor. The WorkerThreadPool executor requires invokeAll() to be called from inside a worker thread it owns (documented at line 169-184); calling from any other thread violates the work-stealing invariants.
Source
Thrown at junit-platform-engine/src/main/java/org/junit/platform/engine/support/hierarchical/WorkerThreadPoolHierarchicalTestExecutorService.java:277
@Nullable
WorkerLease workerLease;
WorkerThread(Runnable runnable, String name) {
super(runnable, name);
}
static @Nullable WorkerThread get() {
if (Thread.currentThread() instanceof WorkerThread workerThread) {
return workerThread;
}
return null;
}
static WorkerThread getOrThrow() {
var workerThread = get();
if (workerThread == null) {
throw new IllegalStateException("Not on a worker thread");
}
return workerThread;
}
WorkerThreadPoolHierarchicalTestExecutorService executor() {
return WorkerThreadPoolHierarchicalTestExecutorService.this;
}
void processQueueEntries(WorkerLease workerLease, BooleanSupplier doneCondition) {
this.workerLease = workerLease;
while (!executor.isShutdown()) {
if (doneCondition.getAsBoolean()) {
logger.trace(() -> "yielding resource lock");
break;
}
if (workQueue.isEmpty()) {
logger.trace(() -> "no queue entries available");
break;View on GitHub (pinned to 956246301e)
Solutions
- Never call invokeAll from outside a worker thread; submit tasks via submit(TestTask) which is safe to call from any thread (line 150-167).
- If you implement Node.execute, run child tasks synchronously or via the framework-provided executor, not on threads you create.
- Ensure your custom engine does not bypass the executor by invoking tasks on raw threads.
- Switch the offending code path to submit() and let the executor schedule the work.
Example fix
// before: calling invokeAll from a non-worker thread executorService.invokeAll(childTasks); // throws 'Not on a worker thread' // after: submit the parent task and let it invokeAll from within a worker executorService.submit(parentTestTask); // parent's execute() may call invokeAll legally
Defensive patterns
Strategy: validation
Validate before calling
// WorkerThread is a nested type; expose a check via your engine if needed.
// Prefer: only call invokeAll from within a Node.Task submitted via submit().
boolean onWorker = Thread.currentThread().getClass().getName().endsWith("WorkerThread"); Try / catch
try {
executorService.invokeAll(tasks);
} catch (IllegalStateException e) {
if (e.getMessage().equals("Not on a worker thread")) {
// re-submit a parent task instead
executorService.submit(wrapAsParentTask(tasks));
return;
}
throw e;
} Prevention
- Only call invokeAll from within a task submitted via submit().
- Never drive test tasks on threads you create.
- Implement Node.execute to let the framework schedule children.
When it happens
Trigger: Invoking WorkerThreadPoolHierarchicalTestExecutorService.invokeAll(...) from the main thread, a ForkJoinPool thread, or any thread that is not a WorkerThread belonging to this executor. Also reachable via WorkerThread.getOrThrow() inside processQueueEntries/runBlocking paths if somehow invoked off-worker.
Common situations: A custom Node.Task or extension that captures the HierarchicalTestExecutorService and calls invokeAll from a separate (non-worker) thread; mixing the WorkerThreadPool executor with code that spawns its own threads to drive test tasks; bugs in engines that submit tasks from outside the executor.
Related errors
- Could not add entry to the queue for task: ${entry.task}
- Task was deferred but should have been executed synchronousl
- Failed to create ForkJoinPool
- Selector ${selector} did not yield unique test descriptor: $
- 'ResourceLockTarget.CHILDREN' is not supported for methods.
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/ed6bf6e21579fff1.json.
Report an issue: GitHub.