{"record":{"id":"60a09509c1389b85","repo":"junit-team/junit5","slug":"d-configuration-errors-n-s","errorCode":null,"errorMessage":"%d configuration errors:%n%s","messagePattern":"(.+?) configuration errors:%n(.+?)","errorType":"exception","errorClass":"PreconditionViolationException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolverFacade.java","lineNumber":389,"sourceCode":"\t\t\t\tparameterDeclarationMapping.put(actualDeclaration, originalDeclaration);\n\t\t\t}\n\t\t}\n\t\treturn errors;\n\t}\n\n\tprivate static String parameterName(ParameterDeclaration actualDeclaration) {\n\t\treturn actualDeclaration.getParameterName().map(name -> \" '\" + name + \"'\").orElse(\"\");\n\t}\n\n\tprivate static <T> T configurationErrorOrSuccess(List<String> errors, Supplier<T> successfulResult) {\n\t\tif (errors.isEmpty()) {\n\t\t\treturn successfulResult.get();\n\t\t}\n\t\telse if (errors.size() == 1) {\n\t\t\tthrow new PreconditionViolationException(\"Configuration error: \" + errors.get(0) + \".\");\n\t\t}\n\t\telse {\n\t\t\tthrow new PreconditionViolationException(\"%d configuration errors:%n%s\".formatted(errors.size(),\n\t\t\t\terrors.stream().collect(joining(lineSeparator() + \"- \", \"- \", \"\"))));\n\t\t}\n\t}\n\n\tprivate static void validateIndexedParameters(\n\t\t\tNavigableMap<Integer, List<FieldParameterDeclaration>> indexedParameters, List<String> errors) {\n\n\t\tif (indexedParameters.isEmpty()) {\n\t\t\treturn;\n\t\t}\n\n\t\tindexedParameters.forEach(\n\t\t\t(index, declarations) -> validateIndexedParameterDeclarations(index, declarations, errors));\n\n\t\tfor (int index = 0; index <= indexedParameters.lastKey(); index++) {\n\t\t\tif (!indexedParameters.containsKey(index)) {\n\t\t\t\terrors.add(\"no field annotated with @Parameter(%d) declared\".formatted(index));\n\t\t\t}","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolverFacade.java#L371-L407","documentation":"Thrown by ResolverFacade.configurationErrorOrSuccess() when there are two or more configuration errors detected during validation of parameter/field declarations. The message includes the count of errors and a bulleted list of each error message. This is the multi-error variant of error 52 — instead of throwing on the first error, the validator collects all errors and reports them together for better developer experience.","triggerScenarios":"Multiple validation errors exist simultaneously when resolving parameters for a @ParameterizedTest or @ParameterizedClass. For example: two @Parameter fields with invalid indices plus an incompatible @AggregateWith annotation, or multiple parameters whose types don't match the argument source.","commonSituations":"Complex parameterized test methods or classes with several parameters where multiple annotations are wrong at once. Copy-pasting a test template and forgetting to update multiple parameter declarations. @ParameterizedClass with several @Parameter fields where the argument source format changed.","solutions":["Read the full error list — each bullet identifies a separate issue to fix","Fix all listed errors before re-running; fixing only one will still leave the test broken","Start with the first error in the list, fix it, then address subsequent ones in order","After fixing, re-run to confirm no new errors surface from the changes"],"exampleFix":"// before — multiple configuration errors\n@ParameterizedClass\n@CsvSource({ \"1,hello,true\" })\nclass MyTest {\n    @Parameter(index = 5)  int a;   // index out of range\n    @Parameter(index = -1) String b; // invalid index\n    @Parameter             boolean c; // missing index, ambiguous\n}\n\n// after — fix all declared errors\n@ParameterizedClass\n@CsvSource({ \"1,hello,true\" })\nclass MyTest {\n    @Parameter(0) int a;\n    @Parameter(1) String b;\n    @Parameter(2) boolean c;\n}","handlingStrategy":"validation","validationCode":"// Pre-validate ALL parameter/field declarations to catch multiple errors early\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Parameter;\nimport java.util.ArrayList;\nimport java.util.List;\n\nstatic List<String> validateAllDeclarations(Class<?> testClass) {\n    List<String> errors = new ArrayList<>();\n    for (Field f : testClass.getDeclaredFields()) {\n        if (f.isAnnotationPresent(org.junit.jupiter.params.Parameter.class)) {\n            int idx = f.getAnnotation(org.junit.jupiter.params.Parameter.class).value();\n            if (idx < 0) errors.add(\"@Parameter field \" + f.getName() + \" has negative index\");\n            if (java.lang.reflect.Modifier.isFinal(f.getModifiers()))\n                errors.add(\"@Parameter field \" + f.getName() + \" is final\");\n        }\n    }\n    return errors; // fix ALL before running\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Address ALL errors listed in the exception message — fixing only some will leave the test broken","Use a pre-validation utility to check all parameter and field declarations at once","When refactoring argument sources, re-validate all parameter annotations in affected test classes"],"tags":["configuration","parameter-resolution","validation","multiple-errors","junit-params"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}