junit-team/junit5 · error · ConversionException

No built-in converter for source type java.lang.String and…

Error message

No built-in converter for source type java.lang.String and target type %s

What it means

Thrown when no registered StringToObjectConverter (including the convention-based FallbackStringToObjectConverter) accepts the target type. Reachable when the type is not a primitive/wrapper, enum, date-time, common java type, or Class, AND it has no single non-private static factory method or constructor accepting a String/CharSequence. Arrays, collections, and maps always fall through to this path.

Solutions

  1. Add a single non-private static factory method (e.g. public static MyType valueOf(String)) or a single-arg String constructor to the target type
  2. Provide a custom ArgumentConverter via @ConvertWith on the parameter
  3. Switch the parameter to a supported type (String, primitive, ...) and construct the object inside the test body
  4. Use @AggregateWith with a custom ArgumentAggregator for multi-field types

Example fix

// before
@ParameterizedTest
@ValueSource(strings = "1,2")
void test(Pair p) { ... }

// after
class Pair {
  final int a, b;
  Pair(int a, int b) { this.a = a; this.b = b; }
  public static Pair valueOf(String s) {
    String[] parts = s.split(",");
    return new Pair(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
  }
}
@ParameterizedTest
@ValueSource(strings = "1,2")
void test(Pair p) { ... }
Defensive patterns

Strategy: fallback

Try / catch

try {
    return ConversionSupport.convert(source, targetType, classLoader);
} catch (ConversionException e) {
    if (e.getMessage().contains("No built-in converter")) {
        // fall back to a custom converter or fail with a clearer message
    }
    throw e;
}

Prevention

When it happens

Trigger: ConversionSupport.convert("...", MyType.class, loader) where MyType has only a multi-arg constructor, only private factories, or multiple overloaded factories (ambiguous -> ignored by the search algorithm). Also convert to int[]/List/Map which JUnit cannot build from a single string.

Common situations: Trying to turn a CSV cell into a value object with no valueOf(String)/fromString(String)/<init>(String); targeting array/Collection/Map types; record types whose only constructor takes multiple components.

Related errors


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

Appendix: 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 f070c699a0)