junit-team/junit5 · error · ArgumentConversionException
%s cannot convert objects of type [%s]. Only source objects
Error message
%s cannot convert objects of type [%s]. Only source objects of type [%s] are supported.
What it means
Thrown by TypedArgumentConverter.convert() when the source argument is not an instance of the converter's declared sourceType. TypedArgumentConverter<S, T> is parameterized by a fixed source and target type; if the actual argument at runtime does not match S, the converter rejects it with this ArgumentConversionException.
Source
Thrown at junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/TypedArgumentConverter.java:74
return convert(source, context.getParameter().getType());
}
@Override
public final @Nullable Object convert(@Nullable Object source, FieldContext context)
throws ArgumentConversionException {
return convert(source, context.getField().getType());
}
private T convert(@Nullable Object source, Class<?> actualTargetType) {
if (source == null) {
return convert(null);
}
if (!this.sourceType.isInstance(source)) {
String message = "%s cannot convert objects of type [%s]. Only source objects of type [%s] are supported.".formatted(
getClass().getSimpleName(), source.getClass().getTypeName(), this.sourceType.getTypeName());
throw new ArgumentConversionException(message);
}
if (!ReflectionUtils.isAssignableTo(this.targetType, actualTargetType)) {
String message = "%s cannot convert to type [%s]. Only target type [%s] is supported.".formatted(
getClass().getSimpleName(), actualTargetType.getTypeName(), this.targetType.getTypeName());
throw new ArgumentConversionException(message);
}
return convert(this.sourceType.cast(source));
}
/**
* Convert the supplied {@code source} object of type {@code S} into an object
* of type {@code T}.
*
* @param source the source object to convert; may be {@code null}
* @return the converted object; may be {@code null} but only if the target
* type is a reference type
* @throws ArgumentConversionException if an error occurs during the
* conversionView on GitHub (pinned to 956246301e)
Solutions
- Ensure the arguments source provides values of the type declared as the converter's sourceType (e.g., String for a TypedArgumentConverter<String, T>)
- If the source type varies, use a general ArgumentConverter or SimpleArgumentConverter instead of TypedArgumentConverter
- Change the converter's sourceType generic parameter to match the actual runtime argument type
- If using @MethodSource, provide Arguments.of(stringValue) instead of Arguments.of(typedObject)
Example fix
// before
class StringToIdConverter extends TypedArgumentConverter<String, Id> {
// ...
}
@ParameterizedTest
@MethodSource("provider")
void test(@ConvertWith(StringToIdConverter.class) Id id) { }
static Stream<Arguments> provider() {
return Stream.of(Arguments.of(123)); // Integer, but converter expects String
}
// after
static Stream<Arguments> provider() {
return Stream.of(Arguments.of("id-123")); // String matches converter sourceType
} Defensive patterns
Strategy: type-guard
Validate before calling
// Check source type compatibility before the converter runs:
Class<?> sourceType = String.class; // the converter's declared source type
if (source != null && !sourceType.isInstance(source)) {
throw new IllegalStateException(
"Expected " + sourceType + " but got " + source.getClass());
} Type guard
// Guard before converting:
if (source instanceof String s) {
// safe to apply TypedArgumentConverter<String, T>
} else {
throw new IllegalArgumentException(
"Converter expects String but received " + (source == null ? "null" : source.getClass()));
} Try / catch
try {
// @ConvertWith(MyConverter.class) on the parameter
} catch (ArgumentConversionException e) {
if (e.getMessage().contains("cannot convert objects of type")) {
// source type mismatch — fix the arguments source
}
throw e;
} Prevention
- Match the arguments source type with the converter's declared sourceType generic parameter
- Use SimpleArgumentConverter or a general ArgumentConverter if the source type varies
- Document the expected source type in the converter's class Javadoc
- Test converters with all source types that the arguments provider can produce
When it happens
Trigger: A custom TypedArgumentConverter<String, Integer> applied via @ConvertMyConverter to a parameterized test parameter, but the argument source provides a non-String value (e.g., an Integer, enum, or POJO from a @MethodSource). The converter's isInstance check fails.
Common situations: Writing a TypedArgumentConverter<String, MyType> and using it with a @MethodSource that provides non-String objects. Reusing a converter designed for String inputs on a source that provides typed objects. Changing the argument source type without updating the converter's sourceType generic.
Related errors
- No built-in converter for source type %s and target type %s
- Argument at index [%d] with value [%s] and type [%s] could n
- 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/dbde8f0ecb04d7ed.json.
Report an issue: GitHub.