junit-team/junit5 · error · JUnitException
State could not be cloned
Error message
State could not be cloned
What it means
Thrown by JupiterEngineExecutionContext.State.clone() if Object.clone() raises CloneNotSupportedException. State explicitly implements Cloneable, so under normal JVM semantics clone() cannot fail; this is a defensive guard against a corrupted/instrumented runtime that violates the Cloneable contract.
Source
Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/JupiterEngineExecutionContext.java:155
ExtensionContext extensionContext;
@Nullable
ThrowableCollector throwableCollector;
State(EngineExecutionListener executionListener, JupiterConfiguration configuration,
LauncherStoreFacade launcherStoreFacade) {
this.executionListener = executionListener;
this.configuration = configuration;
this.launcherStoreFacade = launcherStoreFacade;
}
@Override
public State clone() {
try {
return (State) super.clone();
}
catch (CloneNotSupportedException e) {
throw new JUnitException("State could not be cloned", e);
}
}
}
public static class Builder {
private State originalState;
@Nullable
private State newState = null;
private Builder(State originalState) {
this.originalState = originalState;
}
public Builder withTestInstancesProvider(TestInstancesProvider testInstancesProvider) {
newState().testInstancesProvider = testInstancesProvider;View on GitHub (pinned to 956246301e)
Solutions
- Treat as an environment/JVM defect — verify no bytecode agent is rewriting org.junit.jupiter.engine.execution classes.
- Ensure the junit-jupiter-engine jar is intact (no class corruption); re-fetch the dependency.
- If you forked the engine, confirm State still declares `implements Cloneable`.
Defensive patterns
Strategy: try-catch
Try / catch
// Defensive: catch if you instrument the engine
try { context.extend().build(); }
catch (JUnitException e) {
if (e.getMessage().contains("State could not be cloned")) {
throw new IllegalStateException("Cloneable contract violated — check for bytecode agents", e);
}
throw e;
} Prevention
- Do not run bytecode-rewriting agents that strip Cloneable from engine internals.
- Keep the junit-jupiter-engine jar intact (verify checksums).
- If forking the engine, keep `implements Cloneable` on State.
When it happens
Trigger: Effectively unreachable in a stock JVM because State implements Cloneable. Could only occur if a bytecode-rewriting agent or a hostile classloader strips the Cloneable interface at runtime, or if a future refactor removes `implements Cloneable` from State without removing clone().
Common situations: A testing/coverage/profiling agent that rewrites the State class and drops its Cloneable marker interface; an exotic JVM that does not honor Cloneable.
Related errors
- Chain of InvocationInterceptors never called invocation: <in
- Assumption failed:
- Assumption failed
- This class must not be instantiated
- Implement generateDisplayNameForNestedClass(List<Class<?>>,
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/8b17b20662ae06b9.json.
Report an issue: GitHub.