junit-team/junit5 · error · PreconditionViolationException
Unsupported execution status:%s
Error message
Unsupported execution status:%s
What it means
Thrown as a PreconditionViolationException by SummaryGeneratingListener.executionFinished() in the default branch of the switch over TestExecutionResult.Status. The enum defines exactly three constants — SUCCESSFUL, ABORTED, FAILED — all explicitly handled, so with a conforming engine this branch is effectively unreachable. It is a defensive guard against a TestEngine that returns a null status or a status constant from a newer JUnit version the listener does not know about.
Source
Thrown at junit-platform-launcher/src/main/java/org/junit/platform/launcher/listeners/SummaryGeneratingListener.java:148
summary.containersAborted.incrementAndGet();
}
if (testIdentifier.isTest()) {
summary.testsAborted.incrementAndGet();
}
}
case FAILED -> {
if (testIdentifier.isContainer()) {
summary.containersFailed.incrementAndGet();
}
if (testIdentifier.isTest()) {
summary.testsFailed.incrementAndGet();
}
testExecutionResult.getThrowable().ifPresent(
throwable -> summary.addFailure(testIdentifier, throwable));
}
default -> throw new PreconditionViolationException(
"Unsupported execution status:" + testExecutionResult.getStatus());
}
}
}
View on GitHub (pinned to f070c699a0)
Solutions
- Align all JUnit Platform artifacts to the same version via the junit-bom dependency management.
- If you maintain a custom TestEngine, only ever return one of SUCCESSFUL, ABORTED, or FAILED from TestExecutionResult.
- Run mvn/gradle dependency:tree to confirm no transitive override of junit-platform-launcher or the engine.
- If wrapping the listener, catch PreconditionViolationException and log the offending status so you can report it upstream.
Defensive patterns
Strategy: try-catch
Try / catch
// If you wrap SummaryGeneratingListener to harden a pipeline:
try {
delegate.executionFinished(testIdentifier, testExecutionResult);
} catch (PreconditionViolationException e) {
// An engine returned an unexpected Status. Log the offending status and degrade gracefully.
log.error("Unsupported TestExecutionResult.Status: {}", testExecutionResult.getStatus(), e);
} Prevention
- Keep every org.junit.platform.* artifact on the same version via junit-bom.
- In custom TestEngine implementations, only use TestExecutionResult.successful()/aborted()/failed().
- Run mvn dependency:tree | grep junit-platform to catch transitive version overrides.
- Treat this exception as a bug report against the engine, not an environmental issue.
When it happens
Trigger: A custom TestEngine implementation returns a TestExecutionResult whose Status is null or a value not present in the launcher's TestExecutionResult.Status enum; mixing a newer TestEngine artifact (that adds Status constants) with an older junit-platform-launcher that predates them; reflection/byte-code manipulation that injects an unexpected status. With stock JUnit artifacts on the same version line, this does not occur.
Common situations: Version skew across the JUnit BOM — e.g. a junit-jupiter-engine or a third-party engine ahead of junit-platform-launcher; a hand-written TestEngine that calls TestExecutionResult.status(null) or reinvents the Status enum; snapshot/RC builds where the API is in flux.
Related errors
- Launcher session has already been closed
- @DefaultLocale not configured correctly. When not using a la
- temp directory must be a directory
- thread mode must not be INFERRED
- Configuration error: %s.
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/8988820909f203e4.
Report an issue: GitHub.