junit-team/junit5 · error · ArgumentConversionException
cannot convert objects of type [ ]. Only source objects of…
Error message
%s cannot convert objects of type [%s]. Only source objects of type [%s] are supported.
What it means
Thrown by TypedArgumentConverter when the incoming source object is not an instance of the converter's declared sourceType (S). The generic converter is bound to a specific source type at construction; receiving any other runtime type is a contract violation. The message names the actual runtime class and the expected sourceType.
Solutions
- Align the argument source type with the converter's declared sourceType (e.g. ensure CSV/arguments provide String if the converter is TypedArgumentConverter<String,?>).
- Update the converter's generic sourceType parameter to match the actual incoming type.
- Chain converters or preprocess arguments so the source reaching this converter is the expected type.
- Inspect the message: it prints the actual class and expected class to pinpoint the mismatch.
Example fix
// before
class StringToInt extends TypedArgumentConverter<String, Integer> { ... }
@ParameterizedTest
@ValueSource(ints = 5)
void test(@ConvertWith(StringToInt.class) Integer v) { }
// after
@ParameterizedTest
@ValueSource(strings = "5")
void test(@ConvertWith(StringToInt.class) Integer v) { } Defensive patterns
Strategy: type-guard
Validate before calling
// Verify the source object matches the converter's expected source type before registration
Class<?> expectedSource = String.class; // example
if (!expectedSource.isInstance(sourceObject)) {
throw new IllegalArgumentException("Source must be " + expectedSource.getName());
} Type guard
static boolean matchesSourceType(TypedArgumentConverter<?, ?> converter, Object source) {
return converter.getSourceType().isInstance(source);
} Try / catch
try {
return converter.convert(source, context);
} catch (ArgumentConversionException e) {
if (e.getMessage().contains("cannot convert objects of type")) {
// log and reconfigure source provider to yield the expected type
}
throw e;
} Prevention
- Document the sourceType generic on every TypedArgumentConverter subclass.
- Align the argument source provider output type with the converter's sourceType.
- Unit-test converters in isolation with the exact source type they will receive.
When it happens
Trigger: A subclass of TypedArgumentConverter<String, Integer> (for example) is registered via @ConvertWith but the argument source provides a non-String value (e.g. an Integer or a primitive wrapper). The `!this.sourceType.isInstance(source)` guard fires.
Common situations: Registering a typed converter against a parameter whose source data type differs from what the converter expects (CSV providing numbers as Integer vs String). Refactoring a converter's sourceType generic but forgetting to update the parameter source. Combining @ConvertWith with a source provider that yields a different type than the converter declares.
Related errors
- cannot convert to type [ ]. Only target type [ ] is…
- Cannot convert to
- @EmptySource cannot provide an empty argument
- AnnotationBasedArgumentsProvider does not override the…
- Argument at index [ ] with value [ ] and type [ ] could not…
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/dbde8f0ecb04d7ed.
Report an issue: GitHub.
Appendix: 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 f070c699a0)