junit-team/junit5 · error · ConversionException

Failed to convert String "%s" to type %s

Error message

Failed to convert String "%s" to type %s

What it means

ConversionSupport.convert wraps any non-ConversionException thrown by a built-in converter. It means the source string could be routed to a converter for the target type but the converter rejected it - e.g. NumberFormatException converting "abc" to Integer.

Source

Thrown at junit-platform-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java:135

			return (T) source;
		}

		Class<?> targetTypeToUse = toWrapperType(targetType);
		Optional<StringToObjectConverter> converter = stringToObjectConverters.stream().filter(
			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

  1. Align the source string with the converter's parse rules (Integer.parseInt grammar, ISO-8601 for java.time, TRUE/false/0/1 for Boolean).
  2. Register a custom ArgumentConverter via @ConvertWith for non-standard formats.
  3. Accept the parameter as String and parse it inside the test body.

Example fix

// before
@ParameterizedTest
@CsvSource({ "abc" })
void test(int n) { }

// after
@ParameterizedTest
@CsvSource({ "42" })
void test(int n) { }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-parse the value the way the built-in converter will.
String cell = "42";
try {
    Integer.parseInt(cell);
} catch (NumberFormatException ex) {
    throw new IllegalArgumentException("Cell '" + cell + "' is not a valid Integer", ex);
}

Try / catch

try {
    ConversionSupport.convert(source, targetType, null);
} catch (ConversionException e) {
    if (e.getMessage().startsWith("Failed to convert String")) {
        // align the source string format with the converter, or register a custom ArgumentConverter
    } else throw e;
}

Prevention

When it happens

Trigger: A @CsvSource / @ValueSource string that the target type's converter cannot parse: "abc" for Integer, "xyz" for Boolean, a non-ISO date for LocalDate, etc.

Common situations: Mismatched CSV data format and parameter type; locale-specific number formats; date strings not matching the ISO-8601 format the converter expects.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/6f1b4706168a0482.json. Report an issue: GitHub.