pentaho/pentaho-kettle · error · RhinoRuntimeError

e.toString()

Error message

e.toString()

What it means

The 3-argument form of num2str wraps all its work in a catch (Exception e) and rethrows the exception's toString() as a Rhino runtime error. Any failure — invalid pattern, invalid locale code from EnvUtil.createLocale, DecimalFormat construction errors — surfaces as this opaque e.toString() message rather than a friendly text.

Solutions

  1. Read the e.toString() content to identify whether the pattern or the locale code failed.
  2. Pass exactly a 2-character lowercase language code as third argument (e.g. "en", "de", "fr").
  3. Validate the DecimalFormat pattern independently (arg 2) — common cause.
  4. Simplify: drop the third argument and use the 2-argument form if locale-specific symbols are not essential.

Example fix

// before
var s = num2str(value, "#,##0.00", "de_DE"); // length 5, or bad pattern

// after
var s = num2str(value, "#,##0.00", "de"); // 2-letter code, valid pattern
Defensive patterns

Strategy: validation

Validate before calling

function validateNum2str3(value, pattern, lang) {
  return typeof value === 'number' && !isNaN(value) &&
         typeof pattern === 'string' && pattern.length > 0 &&
         typeof lang === 'string' && lang.length === 2;
}
if (validateNum2str3(v, p, l)) { var s = num2str(v, p, l); }

Try / catch

// The error text is e.toString(); inspect it for DecimalFormat or locale clues.
// Defensive approach: validate args first; avoid triggering the opaque catch.

Prevention

When it happens

Trigger: num2str(number, pattern, lang) throwing any Exception: invalid DecimalFormat pattern in arg 2, or a language code in arg 3 that EnvUtil.createLocale rejects (e.g. num2str(1.5, "#.##", "xyz") with an unprocessable code), or any other internal exception during formatting.

Common situations: Typo in the language code or passing a full locale like "de_DE" when a 2-letter code is expected (length must be exactly 2 to take the locale branch); malformed pattern strings; dynamic pattern values from fields that are empty strings.

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/888beb14b8bd565b. Report an issue: GitHub.

Appendix: source

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

        try {
          if ( isNull( ArgList, new int[] { 0, 1, 2 } ) ) {
            return null;
          } else if ( isUndefined( ArgList, new int[] { 0, 1, 2 } ) ) {
            return (String) Context.getUndefinedValue();
          }
          double sArg1 = Context.toNumber( ArgList[0] );
          if ( Double.isNaN( sArg1 ) ) {
            throw Context.reportRuntimeError( "The first Argument must be a Number." );
          }
          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 );
            sRC = formatter.format( sArg1 );
          }
        } catch ( Exception e ) {
          throw Context.reportRuntimeError( e.toString() );
        }
        break;
      default:
        throw Context.reportRuntimeError( "The function call num2str requires 1, 2, or 3 arguments." );
    }

    return sRC;
  }

  // Converts the given String to a JScript Numeric
  public static Object str2num( Context actualContext, Scriptable actualObject, Object[] ArgList,
    Function FunctionContext ) {
    double dRC = 0.00;
    switch ( ArgList.length ) {
      case 0:
        throw Context.reportRuntimeError( "The function call str2num requires at least 1 argument." );
      case 1:
        try {

View on GitHub (pinned to f3058517a1)