{"record":{"id":"cf4cecd415faf6ee","repo":"junit-team/junit5","slug":"cannot-convert-null-to-s-consider-setting-nulla","errorCode":null,"errorMessage":"Cannot convert null to %s; consider setting 'nullable = true'","messagePattern":"Cannot convert null to (.+?); consider setting 'nullable = true'","errorType":"exception","errorClass":"ArgumentConversionException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/JavaTimeArgumentConverter.java","lineNumber":62,"sourceCode":"\t\tqueries.put(LocalDateTime.class, LocalDateTime::from);\n\t\tqueries.put(LocalTime.class, LocalTime::from);\n\t\tqueries.put(OffsetDateTime.class, OffsetDateTime::from);\n\t\tqueries.put(OffsetTime.class, OffsetTime::from);\n\t\tqueries.put(Year.class, Year::from);\n\t\tqueries.put(YearMonth.class, YearMonth::from);\n\t\tqueries.put(ZonedDateTime.class, ZonedDateTime::from);\n\t\tTEMPORAL_QUERIES = Collections.unmodifiableMap(queries);\n\t}\n\n\t@Override\n\tprotected @Nullable Object convert(@Nullable Object input, Class<?> targetClass,\n\t\t\tJavaTimeConversionPattern annotation) {\n\n\t\tif (input == null) {\n\t\t\tif (annotation.nullable()) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow new ArgumentConversionException(\n\t\t\t\t\"Cannot convert null to \" + targetClass.getName() + \"; consider setting 'nullable = true'\");\n\t\t}\n\t\tTemporalQuery<?> temporalQuery = TEMPORAL_QUERIES.get(targetClass);\n\t\tif (temporalQuery == null) {\n\t\t\tthrow new ArgumentConversionException(\"Cannot convert to \" + targetClass.getName() + \": \" + input);\n\t\t}\n\t\tString pattern = annotation.value();\n\t\tDateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);\n\t\treturn formatter.parse(input.toString(), temporalQuery);\n\t}\n\n}\n","sourceCodeStart":44,"sourceCodeEnd":75,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/JavaTimeArgumentConverter.java#L44-L75","documentation":"Thrown by JavaTimeArgumentConverter when the input argument is null, the target type is a java.time type, and the @JavaTimeConversionPattern annotation does not have nullable = true set (it defaults to false). This converter handles conversion from strings to temporal types (LocalDate, LocalTime, etc.) using a pattern. The message suggests setting 'nullable = true' and includes the target class name.","triggerScenarios":"A @ParameterizedTest parameter of type LocalDate (or other java.time type) annotated with @JavaTimeConversionPattern(\"yyyy-MM-dd\") receives a null argument. This can happen with CSV sources where the date column is empty, @NullSource, or custom providers returning null for that parameter.","commonSituations":"CSV-based tests where a date/time column is optional and sometimes empty. Tests that combine @NullSource or @EmptySource with @JavaTimeConversionPattern-annotated parameters. Database-backed argument sources where a nullable date column returns null for some rows.","solutions":["Set nullable = true on the @JavaTimeConversionPattern annotation to explicitly allow null values","Ensure the argument source never provides null for that parameter by filtering or providing default values","Switch to a wrapper approach: accept null as a String and handle conversion manually, or split null cases into a separate test","If using @CsvSource, provide explicit non-null values for the date column in every row"],"exampleFix":"// before — nullable not set, null input fails\n@ParameterizedTest\n@CsvSource({ \"2024-01-01\", \"\" })\nvoid test(@JavaTimeConversionPattern(\"yyyy-MM-dd\") LocalDate date) { }\n\n// after — set nullable = true\n@ParameterizedTest\n@CsvSource({ \"2024-01-01\", \"\" })\nvoid test(@JavaTimeConversionPattern(value = \"yyyy-MM-dd\", nullable = true) LocalDate date) {\n    if (date == null) return; // handle null case\n    // ... test logic\n}","handlingStrategy":"validation","validationCode":"// Validate that the argument source doesn't provide null for non-nullable java.time params\nimport java.lang.reflect.Parameter;\nimport org.junit.jupiter.params.converter.JavaTimeConversionPattern;\n\nstatic void validateJavaTimeParams(Method testMethod) {\n    for (Parameter p : testMethod.getParameters()) {\n        JavaTimeConversionPattern ann = p.getAnnotation(JavaTimeConversionPattern.class);\n        if (ann != null && !ann.nullable() && mayReceiveNull(p)) {\n            throw new IllegalStateException(\n                \"Parameter \" + p.getName() + \" has @JavaTimeConversionPattern without nullable=true \"\n                + \"but the source may provide null. Set nullable=true or change the source.\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set nullable = true on @JavaTimeConversionPattern for any parameter whose source may contain null/empty values","For optional date/time fields in CSV sources, either filter out null rows or use nullable = true with a null check in the test","Separate null-case tests from value-case tests when possible to avoid mixing nullable and non-nullable patterns"],"tags":["converter","java-time","null","nullable","junit-params"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}