pentaho/pentaho-kettle · error · RuntimeException
Locale " + sArg3 + " is not 2 characters long.
Error message
Locale " + sArg3 + " is not 2 characters long.
What it means
Thrown by the str2date JavaScript function implementation in ScriptAddedFunctions when the third argument (a locale code) is not exactly 2 characters long. The library requires a 2-letter language code (e.g. "en", "de") to build a java.util.Locale via EnvUtil.createLocale before constructing a SimpleDateFormat. It fails fast with this message rather than passing a malformed locale to the JDK.
Solutions
- Pass a 2-letter language code as the third argument, e.g. str2date(str,'yyyy/MM/dd','en') instead of 'en_US'.
- Strip a regional suffix before calling: locale.substring(0,2) if the value looks like 'en_US'.
- Verify the variable/field feeding the locale argument is populated and exactly 2 characters.
- If you need locale+country behavior, note this API only accepts the language code; pre-normalize or use a different parsing approach.
Example fix
// before (JS in a Modified Java Script Value step)
var d = str2date('2024-01-01', 'yyyy-MM-dd', 'en_US');
// after
var d = str2date('2024-01-01', 'yyyy-MM-dd', 'en'); Defensive patterns
Strategy: validation
Validate before calling
function validLocaleArg(loc) { return typeof loc === 'string' && loc.length === 2; }
if (!validLocaleArg(loc)) throw new Error('locale must be a 2-letter code, got: ' + loc); Type guard
function isTwoLetterLocale(v) { return typeof v === 'string' && /^[a-zA-Z]{2}$/.test(v); } Try / catch
try { var d = str2date(s, fmt, loc); } catch (e) { if (String(e.message).indexOf('is not 2 characters long') >= 0) { loc = String(loc).substring(0,2); d = str2date(s, fmt, loc); } else { throw e; } } Prevention
- Always pass 2-letter ISO 639-1 codes ('en','de','fr') as the locale argument
- Strip region suffixes ('en_US' -> 'en') before calling str2date
- Validate the locale variable length before the call
- Never pass null/empty strings as the locale argument
When it happens
Trigger: Calling str2date(dateString, format, locale) in a JavaScript (Rhino/JS) script step where ArgList[2] has length != 2, e.g. str2date('2024/01/01','yyyy/MM/dd','en_US') or 'enu' or '' or null-length strings.
Common situations: Developers copy full BCP-47 tags like 'en-US' or 'en_US' instead of the 2-letter language code; they pass a country code ('US') or a 3-letter code ('eng'); the value comes from a variable/field that is empty or null.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Could not apply the local format for locale " + sArg3 + "…
- Could not convert to the given local format.
- Locale is not 2 characters long.
- Argument of TRUNC of date has to be between 0 and 5
- Argument of TRUNC of date has to be between 0 and 5
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/0f294504e0f8f83c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java:1044
}
break;
case 3:
try {
if ( isNull( ArgList, new int[] { 0, 1, 2 } ) ) {
return null;
} else if ( isUndefined( ArgList, new int[] { 0, 1, 2 } ) ) {
return undefinedValue;
}
sArg1 = (String) ArgList[0];
Format dfFormatter;
sArg2 = (String) ArgList[1];
sArg3 = (String) ArgList[2];
if ( sArg3.length() == 2 ) {
Locale dfLocale = EnvUtil.createLocale( sArg3 );
dfFormatter = new SimpleDateFormat( sArg2, dfLocale );
oRC = dfFormatter.parseObject( sArg1 );
} else {
throw new RuntimeException( "Locale " + sArg3 + " is not 2 characters long." );
}
} catch ( Exception e ) {
throw new RuntimeException( "Could not apply the local format for locale "
+ sArg3 + " with the given format " + sArg2 + " on the string for " + sArg1 + " : " + e.getMessage() );
}
break;
case 4:
try {
if ( isNull( ArgList, new int[] { 0, 1, 2, 3 } ) ) {
return null;
} else if ( isUndefined( ArgList, new int[] { 0, 1, 2, 3 } ) ) {
return undefinedValue;
}
sArg1 = (String) ArgList[0];
DateFormat dfFormatter;
sArg2 = (String) ArgList[1];
sArg3 = (String) ArgList[2];
sArg4 = (String) ArgList[3];View on GitHub (pinned to f3058517a1)