junit-team/junit5 · error · ConversionException
No built-in converter for source type java.lang.String and t
Error message
No built-in converter for source type java.lang.String and target type ${targetType.getTypeName()} What it means
ConversionSupport.convert throws ConversionException when no registered StringToObjectConverter handles the target type and the convention-based fallback (a single non-private static factory method or constructor accepting String/CharSequence) does not apply. The target type is unsupported for String conversion.
Source
Thrown at junit-platform-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java:140
candidate -> candidate.canConvertTo(targetTypeToUse)).findFirst();
if (converter.isPresent()) {
try {
ClassLoader classLoaderToUse = classLoader != null ? classLoader
: ClassLoaderUtils.getDefaultClassLoader();
return (T) converter.get().convert(source, targetTypeToUse, classLoaderToUse);
}
catch (Exception ex) {
if (ex instanceof ConversionException conversionException) {
// simply rethrow it
throw conversionException;
}
// else
throw new ConversionException(
"Failed to convert String \"%s\" to type %s".formatted(source, targetType.getTypeName()), ex);
}
}
throw new ConversionException(
"No built-in converter for source type java.lang.String and target type " + targetType.getTypeName());
}
private static Class<?> toWrapperType(Class<?> targetType) {
Class<?> wrapperType = getWrapperType(targetType);
return wrapperType != null ? wrapperType : targetType;
}
}
View on GitHub (pinned to 956246301e)
Solutions
- Register a custom ArgumentConverter via @ConvertWith on the parameter.
- Add a single non-private static factory method (e.g. static Person from(String)) or a single-String constructor to the target type.
- Change the parameter to String and construct the target object inside the test.
Example fix
// before
@ParameterizedTest
@CsvSource({ "alice,30" })
void test(Person p) { } // Person has no String factory
// after
@ParameterizedTest
@CsvSource({ "alice,30" })
void test(@ConvertWith(PersonConverter.class) Person p) { }
// or give Person: public static Person from(String csv) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Detect unsupported target types before the test runs.
Class<?> target = Person.class;
boolean hasBuiltIn = List.of(
Boolean.class, Character.class, Number.class, Class.class,
java.time.temporal.Temporal.class, java.io.File.class,
java.nio.file.Path.class, java.nio.charset.Charset.class,
java.util.UUID.class, java.net.URI.class, java.net.URL.class,
java.util.Currency.class, java.util.Locale.class)
.stream().anyMatch(c -> c.isAssignableFrom(target));
boolean singleStringFactory =
java.util.Arrays.stream(target.getMethods())
.filter(m -> java.lang.reflect.Modifier.isStatic(m.getModifiers())
&& !java.lang.reflect.Modifier.isPrivate(m.getModifiers())
&& m.getParameterCount() == 1
&& (m.getParameterTypes()[0] == String.class
|| m.getParameterTypes()[0] == CharSequence.class)
&& target.isAssignableFrom(m.getReturnType()))
.count() == 1;
if (!hasBuiltIn && !singleStringFactory && !target.isEnum()) {
throw new IllegalStateException(target + " has no String converter; register @ConvertWith");
} Try / catch
try {
ConversionSupport.convert(source, targetType, null);
} catch (ConversionException e) {
if (e.getMessage().startsWith("No built-in converter")) {
// add a custom ArgumentConverter or a single-String factory/constructor on the target type
} else throw e;
} Prevention
- Register a custom ArgumentConverter via @ConvertWith for domain types.
- Give target types a single non-private static from(String) factory or String constructor.
- Accept String parameters and construct manually when conversion is ambiguous.
When it happens
Trigger: A parameterized-test parameter of an arbitrary type that has no built-in converter, no single-String static factory, and no single-String constructor - e.g. a POJO with multiple or no String-based factories.
Common situations: Adding a new domain-type parameter to a @ParameterizedTest without a converter; type whose factory methods are ambiguous (more than one candidate, which the fallback ignores).
Related errors
- Failed to convert String "%s" to type %s
- %s cannot convert to type [%s]. Only target type [%s] is sup
- @EmptySource cannot provide an empty argument %s: [%s] is no
- Cannot convert null to primitive value of type ${targetType.
- Invoke convert(String, Class<?>, ClassLoader) instead
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/6e308b6cb97ebd36.json.
Report an issue: GitHub.