junit-team/junit5 · error · PreconditionViolationException

@EmptySource cannot provide an empty argument %s: [%s] is no

Error message

@EmptySource cannot provide an empty argument %s: [%s] is not a supported type.

What it means

EmptyArgumentsProvider.provideEmptyArgument throws PreconditionViolationException when the parameter type is not one @EmptySource can make empty: String, List, Set, SortedSet, NavigableSet, Map, SortedMap, NavigableMap, Collection, Iterable, Iterator, ListIterator, arrays, or a Collection/Map subtype with a public no-arg constructor. Primitives and arbitrary objects are unsupported.

Source

Thrown at junit-jupiter-params/src/main/java/org/junit/jupiter/params/provider/EmptyArgumentsProvider.java:117

		}
		if (SortedMap.class.equals(parameterType)) {
			return Stream.of(arguments(Collections.emptySortedMap()));
		}
		if (NavigableMap.class.equals(parameterType)) {
			return Stream.of(arguments(Collections.emptyNavigableMap()));
		}
		if (Collection.class.isAssignableFrom(parameterType) || Map.class.isAssignableFrom(parameterType)) {
			Optional<Constructor<?>> defaultConstructor = getDefaultConstructor(parameterType);
			if (defaultConstructor.isPresent()) {
				return Stream.of(arguments(newInstance(defaultConstructor.get())));
			}
		}
		if (parameterType.isArray()) {
			Object array = Array.newInstance(parameterType.getComponentType(), 0);
			return Stream.of(arguments(array));
		}
		// else
		throw new PreconditionViolationException(
			"@EmptySource cannot provide an empty argument %s: [%s] is not a supported type.".formatted(
				errorDetailsSupplier.get(), parameterType.getName()));
	}

	private static Optional<Constructor<?>> getDefaultConstructor(Class<?> clazz) {
		try {
			return Optional.of(clazz.getConstructor());
		}
		catch (NoSuchMethodException e) {
			return Optional.empty();
		}
	}

	/**
	 * @since 6.1
	 */
	private static class EmptyIterable<E> implements Iterable<E> {

View on GitHub (pinned to 956246301e)

Solutions

  1. Switch the parameter to a supported type (String, an array, or a Collection/Map subtype with a public no-arg constructor).
  2. For primitives, use @ValueSource (e.g. @ValueSource(ints = {0})) instead of @EmptySource.
  3. For custom types, supply an empty instance via a custom ArgumentsProvider or @MethodSource.
  4. Add a public no-arg constructor if the parameter is a Collection/Map subtype you own.

Example fix

// before
@ParameterizedTest
@EmptySource
void test(int n) { }

// after
@ParameterizedTest
@ValueSource(ints = { 0 })
void test(int n) { }
Defensive patterns

Strategy: type-guard

Validate before calling

// Reject @EmptySource on unsupported parameter types up front.
Class<?>[] supported = { String.class, List.class, Set.class, Map.class,
    Collection.class, Iterable.class, Iterator.class, ListIterator.class,
    SortedSet.class, NavigableSet.class, SortedMap.class, NavigableMap.class };
Class<?> pt = method.getParameterTypes()[0];
boolean ok = pt.isArray() || java.util.Arrays.asList(supported).contains(pt)
    || Collection.class.isAssignableFrom(pt) || Map.class.isAssignableFrom(pt);
if (!ok) throw new IllegalArgumentException("@EmptySource not supported for " + pt);

Type guard

// Type guard: only allow @EmptySource on empty-constructible types.
static boolean isEmptyable(Class<?> t) {
    return t == String.class || t.isArray()
        || Collection.class.isAssignableFrom(t)
        || Map.class.isAssignableFrom(t)
        || Iterator.class.isAssignableFrom(t)
        || Iterable.class.isAssignableFrom(t);
}

Try / catch

try {
    // run the parameterized test
} catch (PreconditionViolationException e) {
    if (e.getMessage().contains("not a supported type")) {
        // change the parameter type or switch from @EmptySource to @ValueSource/@MethodSource
    } else throw e;
}

Prevention

When it happens

Trigger: Annotating a parameter of an unsupported type with @EmptySource, e.g. `@EmptySource int n`, `@EmptySource double d`, or `@EmptySource Person p` (Person has no no-arg ctor and is not a Collection/Map subtype).

Common situations: Assuming @EmptySource covers primitives (it does not); using it on a domain type; a Collection subtype whose only constructor takes arguments.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/3b3812b0f908f9eb.json. Report an issue: GitHub.