{"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/956246301e03d757539f7b76dd5a91f298637563/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. The built-in converter only handles String-to-target conversions (via ConversionSupport); non-String objects that are not already the target type have no conversion path.","triggerScenarios":"A @ParameterizedTest or @Parameter field whose source provides a non-String object (e.g., Integer, enum, custom POJO from a @MethodSource) and the parameter type is a different, non-assignable type with no @ConvertWith converter. For example, a @MethodSource providing an Integer for a LocalDate parameter.","commonSituations":"A @MethodSource returning Arguments.of(myObject) where myObject is a custom type and the test method parameter is a different type. Mixing object sources (non-String) with parameter types that need conversion but have no custom converter registered. Providing an enum or POJO where a primitive or temporal type is expected.","solutions":["Provide a @ConvertWith(MyConverter.class) on the parameter to handle the custom type conversion","Change the @MethodSource to provide the argument as a String if the target type has a built-in String converter","Align the source object type with the parameter type (provide the exact type the parameter expects)","Implement a custom ArgumentConverter or SimpleArgumentConverter for the specific source-to-target mapping"],"exampleFix":"// before\n@ParameterizedTest\n@MethodSource(\"provider\")\nvoid test(LocalDate date) { }\nstatic Stream<Arguments> provider() {\n    return Stream.of(Arguments.of(12345)); // Integer -> LocalDate: no converter\n}\n\n// after\n@ParameterizedTest\n@MethodSource(\"provider\")\nvoid test(LocalDate date) { }\nstatic Stream<Arguments> provider() {\n    return Stream.of(Arguments.of(\"2024-01-15\")); // String -> LocalDate: built-in\n}","handlingStrategy":"validation","validationCode":"// Check if the source type is String or assignable before relying on default conversion:\nstatic boolean canConvertByDefault(Object source, Class<?> targetType) {\n    if (source == null) return !targetType.isPrimitive();\n    if (targetType.isAssignableFrom(source.getClass())) return true;\n    return source instanceof String; // String has built-in conversion paths\n}\nif (!canConvertByDefault(arg, targetType)) {\n    throw new IllegalStateException(\"Need a custom @ConvertWith converter for \"\n        + source.getClass() + \" -> \" + targetType);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provide String arguments from sources when the target type has a built-in String converter","Register a @ConvertWith converter for non-String to non-assignable type conversions","Align @MethodSource return types with the parameter types directly to avoid conversion altogether","Test custom ArgumentConverter implementations with representative source objects"],"tags":["argument-converter","type-conversion","parameterized-test","type-mismatch","junit-jupiter-params"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}