junit-team/junit5 · error · ArgumentConversionException
No built-in converter for source type %s and target type %s
Error message
No built-in converter for source type %s and target type %s
What it means
Thrown by DefaultArgumentConverter.convert() when the source object is not null, not assignable to the target type, and not a String. The built-in converter only handles String-to-target conversions (via ConversionSupport); non-String objects that are not already the target type have no conversion path.
Source
Thrown at junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/DefaultArgumentConverter.java:97
"Cannot convert null to primitive value of type " + targetType.getTypeName());
}
return null;
}
if (ReflectionUtils.isAssignableTo(source, targetType)) {
return source;
}
if (source instanceof String string) {
try {
return convert(string, targetType, classLoader);
}
catch (ConversionException ex) {
throw new ArgumentConversionException(ex.getMessage(), ex);
}
}
throw new ArgumentConversionException("No built-in converter for source type %s and target type %s".formatted(
source.getClass().getTypeName(), targetType.getTypeName()));
}
@Nullable
Object convert(@Nullable String source, Class<?> targetType, ClassLoader classLoader) {
return ConversionSupport.convert(source, targetType, classLoader);
}
}
View on GitHub (pinned to 956246301e)
Solutions
- Provide a @ConvertWith(MyConverter.class) on the parameter to handle the custom type conversion
- Change the @MethodSource to provide the argument as a String if the target type has a built-in String converter
- Align the source object type with the parameter type (provide the exact type the parameter expects)
- Implement a custom ArgumentConverter or SimpleArgumentConverter for the specific source-to-target mapping
Example fix
// before
@ParameterizedTest
@MethodSource("provider")
void test(LocalDate date) { }
static Stream<Arguments> provider() {
return Stream.of(Arguments.of(12345)); // Integer -> LocalDate: no converter
}
// after
@ParameterizedTest
@MethodSource("provider")
void test(LocalDate date) { }
static Stream<Arguments> provider() {
return Stream.of(Arguments.of("2024-01-15")); // String -> LocalDate: built-in
} Defensive patterns
Strategy: validation
Validate before calling
// Check if the source type is String or assignable before relying on default conversion:
static boolean canConvertByDefault(Object source, Class<?> targetType) {
if (source == null) return !targetType.isPrimitive();
if (targetType.isAssignableFrom(source.getClass())) return true;
return source instanceof String; // String has built-in conversion paths
}
if (!canConvertByDefault(arg, targetType)) {
throw new IllegalStateException("Need a custom @ConvertWith converter for "
+ source.getClass() + " -> " + targetType);
} Prevention
- Provide String arguments from sources when the target type has a built-in String converter
- Register a @ConvertWith converter for non-String to non-assignable type conversions
- Align @MethodSource return types with the parameter types directly to avoid conversion altogether
- Test custom ArgumentConverter implementations with representative source objects
When it happens
Trigger: A @ParameterizedTest or @Parameter field whose source provides a non-String object (e.g., Integer, enum, custom POJO from a @MethodSource) and the parameter type is a different, non-assignable type with no @ConvertWith converter. For example, a @MethodSource providing an Integer for a LocalDate parameter.
Common situations: A @MethodSource returning Arguments.of(myObject) where myObject is a custom type and the test method parameter is a different type. Mixing object sources (non-String) with parameter types that need conversion but have no custom converter registered. Providing an enum or POJO where a primitive or temporal type is expected.
Related errors
- Argument at index [%d] with value [%s] and type [%s] could n
- %s cannot convert objects of type [%s]. Only source objects
- Cannot convert null to primitive value of type ${targetType.
- Cannot convert null to ${targetClass.getName()}; consider se
- Cannot convert to ${targetClass.getName()}: ${input}
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/e15492bad74d487b.json.
Report an issue: GitHub.