pentaho/pentaho-kettle · error · RuntimeException

e.getMessage()

Error message

e.getMessage()

What it means

ScriptAddedFunctions.str2num parses a string into a number using java.text.DecimalFormat with an optional pattern and locale. Any exception during parsing or pattern/locale construction is rethrown as a RuntimeException whose message is only e.getMessage(), so the original exception type and stack trace are lost. This typically fires when the input string is not parseable as a number under the given pattern/locale.

Solutions

  1. Verify the string exactly matches the DecimalFormat pattern and locale (e.g. use pattern '#,##0.00' with locale 'en' for '1,234.56').
  2. Normalize the input string first (trim, fix decimal separator) before calling str2num.
  3. Pre-check with isNum(str) in the script before converting.
  4. Catch the RuntimeException in the script and return a default value instead of failing the row.

Example fix

// before
var n = str2num('12,5', '#,###', 'en'); // throws
// after
var n = isNum('12,5') ? str2num('12,5', '#,##0.0', 'en') : 0;
Defensive patterns

Strategy: validation

Validate before calling

function safeStr2num(v, pattern, locale) {
  if (v === null || v === undefined) return null;
  var s = String(v).trim();
  if (!/^[+-]?[0-9.,eE+-]+$/.test(s)) return null;
  try { return str2num(s, pattern || '#,##0.########', locale || 'en'); }
  catch (e) { return null; }
}

Type guard

function isNumericString(v) {
  return typeof v === 'string' && v.trim() !== '' && !isNaN(Number(v.trim()));
}

Try / catch

try {
  var n = str2num(s, pattern, locale);
} catch (e) {
  // log e.message, route row to error handling / default value
  var n = null;
}

Prevention

When it happens

Trigger: Calling str2num(s) / str2num(s, pattern) / str2num(s, pattern, locale) inside a JavaScript (JS) transformation step where s cannot be parsed by DecimalFormat with the supplied pattern and locale (e.g. '12,5' with pattern '#,###' in an English locale).

Common situations: Locale mismatches (decimal comma vs dot), wrong DecimalFormat pattern strings, strings containing currency symbols or whitespace, null/undefined values passed from the JS step.

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/0a1c7515ce5d6f71. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/script/ScriptAddedFunctions.java:1425

        // 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 undefinedValue;
          }
          String sArg1 = (String) ArgList[0];
          String sArg2 = (String) ArgList[1];
          String sArg3 = (String) 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 new RuntimeException( e.getMessage() );
        }
        break;
      default:
        throw new RuntimeException( "The function call str2num requires 1, 2, or 3 arguments." );
    }
    return new Double( dRC );
  }

  public static Object isNum( ScriptEngine actualContext, Bindings actualObject, Object[] ArgList,
    Object FunctionContext ) {

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

View on GitHub (pinned to f3058517a1)