pentaho/pentaho-kettle · error · RhinoRuntimeError

e.getMessage()

Error message

e.getMessage()

What it means

This is the 3-argument branch of the str2num function (value, format pattern, locale). It creates a DecimalFormat with DecimalFormatSymbols built from EnvUtil.createLocale on the lowercased third argument, then parses the value. Any exception during locale resolution, pattern compilation, or parsing is caught and rethrown verbatim as e.getMessage(), so the reported message is the underlying cause's message rather than a descriptive prefix.

Solutions

  1. Read the thrown e.getMessage() to identify whether the cause is the locale, the pattern, or the value
  2. Use a valid ISO locale code (language, optionally country) as the third argument, e.g. str2num(v, '#,##0.00', 'en')
  3. Confirm the value parses under the locale's decimal separator (comma vs dot)
  4. Validate with isNum(v) before calling str2num
  5. Null-check the field: a missing incoming field surfaces here as a parse/NPE

Example fix

// before
var n = str2num('1.234,56', '#,##0.00', 'en'); // '1.234,56' doesn't parse with EN symbols
// after
var n = str2num('1.234,56', '#,##0.00', 'de'); // match locale to data
Defensive patterns

Strategy: validation

Validate before calling

function safeStr2numLocale(v, fmt, loc) {
  if (v === null || v === undefined) return null;
  if (!/^[a-z]{2}(_[A-Z]{2})?$/.test(loc)) return null;
  return str2num(String(v).trim(), fmt, loc);
}

Type guard

function isLocaleTag(s) { return typeof s === 'string' && /^[a-z]{2}(_[A-Z]{2})?$/.test(s); }

Try / catch

try {
  var n = str2num(value, '#,##0.00', 'de');
} catch (e) {
  // this branch rethrows the raw cause message — log it verbatim
  Logger.LogError('str2num(3-arg) failed: ' + e.message);
  n = null;
}

Prevention

When it happens

Trigger: str2num('1,234.56', '#,##0.00', 'us') with an unknown/invalid locale string; str2num('abc', '#,##0.00', 'en') where the value doesn't parse under the given locale's symbols; a null value combined with a locale argument.

Common situations: Converting multi-region source data in one transformation, passing an empty or misspelled locale tag ('deutsch' instead of 'de'), or format/value mismatch when concatenating fields from different file formats.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/6cd293911614631d. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesAddedFunctions.java:1460

        // break;
      case 3:
        try {
          if ( isNull( ArgList, new int[] { 0, 1, 2 } ) ) {
            return new Double( Double.NaN );
          } else if ( isUndefined( ArgList, new int[] { 0, 1, 2 } ) ) {
            return Context.getUndefinedValue();
          }
          String sArg1 = Context.toString( ArgList[0] );
          String sArg2 = Context.toString( ArgList[1] );
          String sArg3 = Context.toString( ArgList[2] );
          if ( sArg3.length() == 2 ) {
            DecimalFormatSymbols dfs = new DecimalFormatSymbols( EnvUtil.createLocale( sArg3.toLowerCase() ) );
            DecimalFormat formatter = new DecimalFormat( sArg2, dfs );
            dRC = ( formatter.parse( sArg1 ) ).doubleValue();
            return new Double( dRC );
          }
        } catch ( Exception e ) {
          throw Context.reportRuntimeError( e.getMessage() );
        }
        break;
      default:
        throw Context.reportRuntimeError( "The function call str2num requires 1, 2, or 3 arguments." );
    }
    return new Double( dRC );
  }

  public static Object isNum( Context actualContext, Scriptable actualObject, Object[] ArgList,
    Function FunctionContext ) {

    if ( ArgList.length == 1 ) {
      try {
        if ( isNull( ArgList[0] ) ) {
          return null;
        } else if ( isUndefined( ArgList[0] ) ) {
          return Context.getUndefinedValue();
        }

View on GitHub (pinned to f3058517a1)