{"record":{"id":"4bde7c7df2169ff1","repo":"pentaho/pentaho-kettle","slug":"can-t-convert-a-string-to-a-date","errorCode":null,"errorMessage":"Can't convert a string to a date","messagePattern":"Can't convert a string to a date","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/util/JavaScriptUtils.java","lineNumber":222,"sourceCode":"          return null;\n        }\n      } catch ( Exception e2 ) {\n        String string = (String) Context.jsToJava( value, String.class );\n        return new BigDecimal( string );\n      }\n    }\n  }\n\n  private static Date convertValueToDate( Object value ) throws KettleValueException {\n    try {\n      Value v = (Value) Context.jsToJava( value, Value.class );\n      return v.getDate();\n    } catch ( Exception e2 ) {\n      try {\n        String string = Context.toString( value );\n        return XMLHandler.stringToDate( string );\n      } catch ( Exception e3 ) {\n        throw new KettleValueException( \"Can't convert a string to a date\" );\n      }\n    }\n  }\n}\n","sourceCodeStart":204,"sourceCodeEnd":227,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/util/JavaScriptUtils.java#L204-L227","documentation":"convertValueToDate() first tries Context.jsToJava(value, Date.class); if that fails it tries to interpret the value as a string and parse it with XMLHandler.stringToDate(). When both attempts fail, it throws KettleValueException('Can't convert a string to a date'). The string form of the JS value is not in the expected date format (XML/ISO yyyy-MM-dd'T'HH:mm:ss.SSS).","triggerScenarios":"A BigNumber/Number/Boolean or an arbitrarily formatted string value is routed to a Date output field; the fallback string conversion yields text that XMLHandler.stringToDate cannot parse (e.g. '12/31/2024', 'yesterday').","commonSituations":"Locale-formatted dates from spreadsheets or CSV ('31-12-2024'); timestamps as epoch millis passed as numbers; users assuming the JS step parses arbitrary date strings.","solutions":["Return a JavaScript Date object (new Date(...)) instead of a string from the script.","Parse the string in the script with a known format before assigning it to the Date field.","Use the step's field metadata / a Select Values or Calculator step to apply the correct date format mask matching the source string."],"exampleFix":"// before\nvar orderDate = \"31/12/2024\"; // cannot be parsed\n// after\nvar parts = orderDate.split(\"/\");\nvar orderDate = new Date(+parts[2], +parts[1]-1, +parts[0]); // JS Date object","handlingStrategy":"validation","validationCode":"// in the script, before assigning:\nvar d = new Date(value); // or parse with a fixed format\nif (isNaN(d.getTime())) throw new Error(\"Unparseable date: \" + value);","typeGuard":"function isDateLike(v) {\n  return v instanceof Date || !isNaN(Date.parse(String(v)));\n}","tryCatchPattern":"try {\n  Object date = JavaScriptUtils.convertFromJs(context, value, fieldName, \"java.util.Date\");\n} catch (KettleValueException e) {\n  logError(\"Field \" + fieldName + \": value is not a parseable date: \" + Context.toString(value));\n}","preventionTips":["Produce real JS Date objects for Date-typed fields instead of formatted strings.","Agree on ISO 8601 (yyyy-MM-dd'T'HH:mm:ss.SSS) if strings must be passed.","Convert locale-formatted dates in a dedicated parsing step before the JS step.","Never pass epoch-millis numbers directly to Date-typed fields without conversion."],"tags":["javascript","date","type-conversion","etl"],"backgroundTag":"invalid-date-format","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}