pentaho/pentaho-kettle · error · KettleValueException

Couldn't convert Number to String

Error message

Couldn't convert Number to String 

What it means

Thrown by Value.to_char() for numeric values when the DecimalFormat (nf.format(getNumber())) fails. On failure the value is set to a null String and KettleValueException is rethrown with the underlying exception text appended. This is the NUM2STR conversion path for Number/Integer values.

Solutions

  1. Validate the decimal format pattern before use — it must be valid Java DecimalFormat syntax, not Oracle TO_CHAR syntax.
  2. Simplify the pattern (e.g. '#,##0.00') to test whether the mask is the problem.
  3. Check the appended e.toString() in the message to identify the exact format failure.
  4. Handle null result: the value is set to null String before the throw, so downstream code must expect a null on failure.

Example fix

// before
value.to_char("999,999.00"); // Oracle-style pattern, DecimalFormat throws
// after
value.to_char("#,##0.00"); // valid DecimalFormat pattern
Defensive patterns

Strategy: try-catch

Validate before calling

try { new java.text.DecimalFormat(pattern); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Invalid numeric format pattern: " + pattern); }

Try / catch

try { result = value.to_char(pattern); } catch (KettleValueException e) { log.error("NUM2STR format failed: " + e.getMessage()); result = String.valueOf(value.getNumber()); }

Prevention

When it happens

Trigger: Calling value.to_char() on a numeric Value with a format pattern that DecimalFormat rejects or cannot apply (e.g. 'L' currency symbol with no locale support, illegal pattern characters), or a number that the chosen format cannot render (NaN/Infinity with certain patterns).

Common situations: User-supplied format masks with typos (e.g. '##0.00x'); locale-dependent currency symbols unavailable at runtime; migrating format strings from Oracle TO_CHAR to Java DecimalFormat syntax.

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/48c2d93d6cfb3014. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/compatibility/Value.java:3079

        if ( currencySymbol != null && currencySymbol.length() > 0 ) {
          dfs.setCurrencySymbol( currencySymbol );
        }
        if ( groupingSymbol != null && groupingSymbol.length() > 0 ) {
          dfs.setGroupingSeparator( groupingSymbol.charAt( 0 ) );
        }
        if ( decimalSymbol != null && decimalSymbol.length() > 0 ) {
          dfs.setDecimalSeparator( decimalSymbol.charAt( 0 ) );
        }
        df.setDecimalFormatSymbols( dfs ); // in case of 4, 3 or 2
        if ( format != null && format.length() > 0 ) {
          df.applyPattern( format );
        }
        try {
          setValue( nf.format( getNumber() ) );
        } catch ( Exception e ) {
          setType( VALUE_TYPE_STRING );
          setNull();
          throw new KettleValueException( "Couldn't convert Number to String " + e.toString() );
        }
      } else {
        throw new KettleValueException( "Function NUM2STR only works on Numbers and Integers" );
      }
    }
    return this;
  }

  // date: TO_CHAR( <date> , 'yyyy/mm/dd HH:mm:ss'
  public Value dat2str() throws KettleValueException {
    return dat2str( null, null );
  }

  public Value dat2str( String arg0 ) throws KettleValueException {
    return dat2str( arg0, null );
  }

  public Value dat2str( String arg0, String arg1 ) throws KettleValueException {

View on GitHub (pinned to f3058517a1)