junit-team/junit5 · error · JUnitException
Failed to find constructor for %s [%s]. Please ensure that a
Error message
Failed to find constructor for %s [%s]. Please ensure that a no-argument or a single constructor exists.
What it means
Thrown by ParameterizedTestSpiInstantiator.findBestConstructor() when instantiating a custom SPI implementation (ArgumentsProvider, ArgumentConverter, or ArgumentsAggregator) whose class has multiple constructors and none of them is a no-argument (default) constructor. The instantiator first checks for a single constructor (returns it regardless of arity), then checks for a no-arg constructor; if neither exists, this error is thrown.
Source
Thrown at junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedTestSpiInstantiator.java:72
Constructor<?>[] constructors = implementationClass.getDeclaredConstructors();
// Single constructor?
if (constructors.length == 1) {
return constructors[0];
}
// Find default constructor.
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 0) {
return constructor;
}
}
// Otherwise...
String message = """
Failed to find constructor for %s [%s]. \
Please ensure that a no-argument or a single constructor exists.""".formatted(
spiInterface.getSimpleName(), implementationClass.getName());
throw new JUnitException(message);
}
private ParameterizedTestSpiInstantiator() {
}
}
View on GitHub (pinned to 956246301e)
Solutions
- Add an explicit no-argument constructor to the custom SPI class
- If the class has exactly one constructor with parameters, remove extra constructors so there is a single constructor (the instantiator accepts any single-constructor class)
- Ensure the class is a top-level class or a static nested class (not a non-static inner class)
Example fix
// before
static class MyProvider implements ArgumentsProvider {
MyProvider(String config) { }
MyProvider(int x) { }
// no no-arg constructor
public Stream<? extends Arguments> provideArguments(ParameterDeclarations p, ExtensionContext c) { ... }
}
// after
static class MyProvider implements ArgumentsProvider {
MyProvider() { } // no-arg constructor added
public Stream<? extends Arguments> provideArguments(ParameterDeclarations p, ExtensionContext c) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// Validate SPI class constructor structure before registering:
static void validateSpiClass(Class<?> implClass) {
Constructor<?>[] ctors = implClass.getDeclaredConstructors();
boolean hasNoArg = Arrays.stream(ctors).anyMatch(c -> c.getParameterCount() == 0);
if (ctors.length > 1 && !hasNoArg) {
throw new IllegalStateException(implClass.getName()
+ " must have a no-arg or single constructor");
}
if (implClass.isMemberClass() && !Modifier.isStatic(implClass.getModifiers())) {
throw new IllegalStateException(implClass.getName() + " must be static nested or top-level");
}
} Prevention
- Give custom ArgumentsProvider/ArgumentConverter/ArgumentsAggregator classes a no-arg constructor
- Ensure SPI implementation classes are top-level or static nested classes, never non-static inner classes
- If multiple constructors are needed, always include an explicit no-argument one
- Keep SPI classes simple — a single no-arg constructor is the safest design
When it happens
Trigger: Referencing a custom class via @ArgumentsSource(MyProvider.class), @ConvertWith(MyConverter.class), or @AggregateWith(MyAggregator.class) where that class declares multiple constructors and none has zero parameters. The SPI classes must be top-level or static nested classes with either a single constructor or an accessible no-arg constructor.
Common situations: Writing a custom ArgumentsProvider/ArgumentConverter with convenience constructors (e.g., a configuration constructor alongside a no-arg one) but forgetting the no-arg constructor, or adding a second constructor during refactoring. Using an inner (non-static) class as a provider, which also fails an earlier check.
Related errors
- Constructor injection is not supported for @ParameterizedCla
- Configuration error: You must configure at least one set of
- The display name pattern defined for the parameterized test
- When the display name pattern for a @%s contains %s, the arg
- Configuration error: <error>.
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/ff0470155cc8b298.json.
Report an issue: GitHub.