{"id":"ff0470155cc8b298","repo":"junit-team/junit5","slug":"failed-to-find-constructor-for-s-s-please-ens","errorCode":null,"errorMessage":"Failed to find constructor for %s [%s]. Please ensure that a no-argument or a single constructor exists.","messagePattern":"Failed to find constructor for (.+?) \\[(.+?)\\]\\. Please ensure that a no-argument or a single constructor exists\\.","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedTestSpiInstantiator.java","lineNumber":72,"sourceCode":"\n\t\tConstructor<?>[] constructors = implementationClass.getDeclaredConstructors();\n\n\t\t// Single constructor?\n\t\tif (constructors.length == 1) {\n\t\t\treturn constructors[0];\n\t\t}\n\t\t// Find default constructor.\n\t\tfor (Constructor<?> constructor : constructors) {\n\t\t\tif (constructor.getParameterCount() == 0) {\n\t\t\t\treturn constructor;\n\t\t\t}\n\t\t}\n\t\t// Otherwise...\n\t\tString message = \"\"\"\n\t\t\t\tFailed to find constructor for %s [%s]. \\\n\t\t\t\tPlease ensure that a no-argument or a single constructor exists.\"\"\".formatted(\n\t\t\tspiInterface.getSimpleName(), implementationClass.getName());\n\t\tthrow new JUnitException(message);\n\t}\n\n\tprivate ParameterizedTestSpiInstantiator() {\n\t}\n\n}\n","sourceCodeStart":54,"sourceCodeEnd":79,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ParameterizedTestSpiInstantiator.java#L54-L79","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nstatic class MyProvider implements ArgumentsProvider {\n    MyProvider(String config) { }\n    MyProvider(int x) { }\n    // no no-arg constructor\n    public Stream<? extends Arguments> provideArguments(ParameterDeclarations p, ExtensionContext c) { ... }\n}\n\n// after\nstatic class MyProvider implements ArgumentsProvider {\n    MyProvider() { } // no-arg constructor added\n    public Stream<? extends Arguments> provideArguments(ParameterDeclarations p, ExtensionContext c) { ... }\n}","handlingStrategy":"validation","validationCode":"// Validate SPI class constructor structure before registering:\nstatic void validateSpiClass(Class<?> implClass) {\n    Constructor<?>[] ctors = implClass.getDeclaredConstructors();\n    boolean hasNoArg = Arrays.stream(ctors).anyMatch(c -> c.getParameterCount() == 0);\n    if (ctors.length > 1 && !hasNoArg) {\n        throw new IllegalStateException(implClass.getName()\n            + \" must have a no-arg or single constructor\");\n    }\n    if (implClass.isMemberClass() && !Modifier.isStatic(implClass.getModifiers())) {\n        throw new IllegalStateException(implClass.getName() + \" must be static nested or top-level\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["spi","arguments-provider","argument-converter","constructor","configuration","junit-jupiter-params"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}