junit-team/junit5 · error · ConversionException

Cannot convert null to primitive value of type %s

Error message

Cannot convert null to primitive value of type %s

What it means

Thrown by ConversionSupport.convert when the source string is null but the target type is a primitive (int, boolean, char, ...). Java primitives cannot hold null, so the conversion is impossible and JUnit treats it as a hard contract violation rather than returning a default. The targetType.getTypeName() is interpolated into the message.

Source

Thrown at junit-platform-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java:110

	 *
	 * @param source the source {@code String} to convert; may be {@code null}
	 * but only if the target type is a reference type
	 * @param targetType the target type the source should be converted into;
	 * never {@code null}
	 * @param classLoader the {@code ClassLoader} to use; may be {@code null} to
	 * use the default {@code ClassLoader}
	 * @param <T> the type of the target
	 * @return the converted object; may be {@code null} but only if the target
	 * type is a reference type
	 *
	 * @since 1.11
	 */
	@SuppressWarnings("unchecked")
	public static <T> @Nullable T convert(@Nullable String source, Class<T> targetType,
			@Nullable ClassLoader classLoader) {
		if (source == null) {
			if (targetType.isPrimitive()) {
				throw new ConversionException(
					"Cannot convert null to primitive value of type " + targetType.getTypeName());
			}
			return null;
		}

		if (String.class.equals(targetType)) {
			return (T) source;
		}

		Class<?> targetTypeToUse = toWrapperType(targetType);
		Optional<StringToObjectConverter> converter = stringToObjectConverters.stream().filter(
			candidate -> candidate.canConvertTo(targetTypeToUse)).findFirst();
		if (converter.isPresent()) {
			try {
				ClassLoader classLoaderToUse = classLoader != null ? classLoader
						: ClassLoaderUtils.getDefaultClassLoader();
				return (T) converter.get().convert(source, targetTypeToUse, classLoaderToUse);
			}

View on GitHub (pinned to f070c699a0)

Solutions

  1. Change the primitive parameter to its wrapper type (int -> Integer, boolean -> Boolean) so null is accepted
  2. Remove null-producing argument sources (@NullSource, @NullAndEmptySource) from tests that have primitive parameters
  3. Guard the @MethodSource factory to never emit null for primitive slots
  4. Provide a custom ArgumentConverter (@ConvertWith) that substitutes a sensible default instead of null

Example fix

// before
@ParameterizedTest
@NullSource
void test(int port) { ... }

// after
@ParameterizedTest
@NullSource
void test(Integer port) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling convert
if (source == null && targetType.isPrimitive()) {
    // supply a default or switch to the wrapper type
    return /* default */;
}
return ConversionSupport.convert(source, targetType, classLoader);

Type guard

static boolean canConvertNullTo(Class<?> targetType) {
    return targetType != null && !targetType.isPrimitive();
}

Prevention

When it happens

Trigger: Calling ConversionSupport.convert(null, int.class, loader) (or any primitive .class), or a parameterized-test argument source feeding null into a primitive parameter: @NullSource / @NullAndEmptySource on an int param, a @MethodSource returning null for a primitive slot, or an @CsvSource empty column mapped to a primitive.

Common situations: @ParameterizedTest with primitive parameter types combined with null-producing argument sources (@NullSource, @NullAndEmptySource, a @MethodSource that yields null); @CsvFileSource with empty/nullValues cells hitting a primitive param; custom ArgumentAggregator returning null for a primitive slot.

Related errors


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