junit-team/junit5 · error · PreconditionViolationException

configuration errors:%n

Error message

%d configuration errors:%n%s

What it means

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.

Solutions

  1. Read the full error list — each bullet identifies a separate issue to fix
  2. Fix all listed errors before re-running; fixing only one will still leave the test broken
  3. Start with the first error in the list, fix it, then address subsequent ones in order
  4. After fixing, re-run to confirm no new errors surface from the changes

Example fix

// before — multiple configuration errors
@ParameterizedClass
@CsvSource({ "1,hello,true" })
class MyTest {
    @Parameter(index = 5)  int a;   // index out of range
    @Parameter(index = -1) String b; // invalid index
    @Parameter             boolean c; // missing index, ambiguous
}

// after — fix all declared errors
@ParameterizedClass
@CsvSource({ "1,hello,true" })
class MyTest {
    @Parameter(0) int a;
    @Parameter(1) String b;
    @Parameter(2) boolean c;
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate ALL parameter/field declarations to catch multiple errors early
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

static List<String> validateAllDeclarations(Class<?> testClass) {
    List<String> errors = new ArrayList<>();
    for (Field f : testClass.getDeclaredFields()) {
        if (f.isAnnotationPresent(org.junit.jupiter.params.Parameter.class)) {
            int idx = f.getAnnotation(org.junit.jupiter.params.Parameter.class).value();
            if (idx < 0) errors.add("@Parameter field " + f.getName() + " has negative index");
            if (java.lang.reflect.Modifier.isFinal(f.getModifiers()))
                errors.add("@Parameter field " + f.getName() + " is final");
        }
    }
    return errors; // fix ALL before running
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/60a09509c1389b85. Report an issue: GitHub.

Appendix: source

Thrown at junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolverFacade.java:389

				parameterDeclarationMapping.put(actualDeclaration, originalDeclaration);
			}
		}
		return errors;
	}

	private static String parameterName(ParameterDeclaration actualDeclaration) {
		return actualDeclaration.getParameterName().map(name -> " '" + name + "'").orElse("");
	}

	private static <T> T configurationErrorOrSuccess(List<String> errors, Supplier<T> successfulResult) {
		if (errors.isEmpty()) {
			return successfulResult.get();
		}
		else if (errors.size() == 1) {
			throw new PreconditionViolationException("Configuration error: " + errors.get(0) + ".");
		}
		else {
			throw new PreconditionViolationException("%d configuration errors:%n%s".formatted(errors.size(),
				errors.stream().collect(joining(lineSeparator() + "- ", "- ", ""))));
		}
	}

	private static void validateIndexedParameters(
			NavigableMap<Integer, List<FieldParameterDeclaration>> indexedParameters, List<String> errors) {

		if (indexedParameters.isEmpty()) {
			return;
		}

		indexedParameters.forEach(
			(index, declarations) -> validateIndexedParameterDeclarations(index, declarations, errors));

		for (int index = 0; index <= indexedParameters.lastKey(); index++) {
			if (!indexedParameters.containsKey(index)) {
				errors.add("no field annotated with @Parameter(%d) declared".formatted(index));
			}

View on GitHub (pinned to f070c699a0)