{"record":{"id":"e15492bad74d487b","repo":"junit-team/junit5","slug":"no-built-in-converter-for-source-type-s-and-targe","errorCode":null,"errorMessage":"No built-in converter for source type %s and target type %s","messagePattern":"No built-in converter for source type (.+?) and target type (.+?)","errorType":"exception","errorClass":"ArgumentConversionException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/DefaultArgumentConverter.java","lineNumber":97,"sourceCode":"\t\t\t\t\t\"Cannot convert null to primitive value of type \" + targetType.getTypeName());\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tif (ReflectionUtils.isAssignableTo(source, targetType)) {\n\t\t\treturn source;\n\t\t}\n\n\t\tif (source instanceof String string) {\n\t\t\ttry {\n\t\t\t\treturn convert(string, targetType, classLoader);\n\t\t\t}\n\t\t\tcatch (ConversionException ex) {\n\t\t\t\tthrow new ArgumentConversionException(ex.getMessage(), ex);\n\t\t\t}\n\t\t}\n\n\t\tthrow new ArgumentConversionException(\"No built-in converter for source type %s and target type %s\".formatted(\n\t\t\tsource.getClass().getTypeName(), targetType.getTypeName()));\n\t}\n\n\t@Nullable\n\tObject convert(@Nullable String source, Class<?> targetType, ClassLoader classLoader) {\n\t\treturn ConversionSupport.convert(source, targetType, classLoader);\n\t}\n\n}\n","sourceCodeStart":79,"sourceCodeEnd":107,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/DefaultArgumentConverter.java#L79-L107","documentation":"Thrown by DefaultArgumentConverter.convert() when the source object is not null, not assignable to the target type, and not a String (so string-based conversion can't be attempted). The DefaultArgumentConverter can only convert: (1) source already assignable to target, (2) String source via ConversionSupport. For any other source type that doesn't match, there is no built-in converter. The message includes both source and target type names.","triggerScenarios":"Pass a non-String, non-assignable object as a parameterized test argument. For example: a BigDecimal parameter with a LocalDate argument source, or an Integer parameter with a Double value. This occurs when a custom ArgumentsProvider returns objects whose types don't match the parameter declarations and aren't Strings.","commonSituations":"Custom ArgumentsProvider implementations that return domain objects instead of Strings or directly-matching types. Argument sources that read from JSON/databases and return typed objects that don't match the test parameter declarations. Mixing @MethodSource providers that return different object types than expected.","solutions":["Ensure the ArgumentsProvider returns values whose types are assignable to (or String-convertible to) the parameter types","Register a custom ArgumentConverter via @ConvertWith to handle the specific source-to-target conversion","If using @MethodSource, verify the returned argument types match the parameter declarations exactly","Convert arguments to Strings in the provider if the built-in String-based converters can handle the target type"],"exampleFix":"// before — provider returns wrong type\n@ParameterizedTest\n@MethodSource(\"data\")\nvoid test(LocalDate date) { }\n\nstatic Stream<Arguments> data() {\n    return Stream.of(Arguments.of(java.util.Date.from(Instant.now()))); // Date ≠ LocalDate\n}\n\n// after — return matching types or add a converter\nstatic Stream<Arguments> data() {\n    return Stream.of(Arguments.of(LocalDate.now())); // types match\n}\n\n// OR use @ConvertWith:\n@ParameterizedTest\n@MethodSource(\"data\")\nvoid test(@ConvertWith(DateToLocalDateConverter.class) LocalDate date) { }","handlingStrategy":"validation","validationCode":"// Validate argument types against parameter types before running\nimport org.junit.platform.commons.util.ReflectionUtils;\n\nstatic boolean isConvertible(Object source, Class<?> targetType) {\n    if (source == null) return !targetType.isPrimitive();\n    if (ReflectionUtils.isAssignableTo(source, targetType)) return true;\n    if (source instanceof String) return true; // built-in String conversion may handle it\n    return false; // no built-in converter for non-String, non-assignable\n}\n\n// Usage: validate all arguments from the provider before returning them","typeGuard":"// Type guard for checking source-target convertibility\nstatic boolean canConvert(Object source, Class<?> target) {\n    if (source == null) return !target.isPrimitive();\n    if (target.isAssignableFrom(source.getClass())) return true;\n    return source instanceof String; // String can attempt built-in conversion\n}","tryCatchPattern":null,"preventionTips":["Ensure ArgumentsProvider implementations return values that are either: assignable to the parameter type, or Strings that the built-in converter can parse","For complex source types (non-String domain objects), register a custom ArgumentConverter via @ConvertWith","Convert domain objects to Strings in the provider if the target type has a built-in String converter"],"tags":["converter","type-mismatch","no-converter","argument-source","junit-params"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}