pentaho/pentaho-kettle · error · KettleValueException

Function NUM2STR only works on Numbers and Integers

Error message

Function NUM2STR only works on Numbers and Integers

What it means

Thrown by Value.to_char() (NUM2STR) when the receiving Value is neither Number nor Integer. The function only formats numeric types through DecimalFormat; String, Date, Boolean, BigNumber, and Binary types raise KettleValueException.

Solutions

  1. Check the value type before calling: use the date overload for Date values and ensure numbers are Number/Integer.
  2. Convert BigNumber values to Number (setValue with getNumber()) if acceptable precision-wise.
  3. Fix field metadata upstream so the column arrives as Number/Integer.
  4. Catch KettleValueException and fall back to String.valueOf(value.getNumber()) style conversion.

Example fix

// before
Value s = bigDecimalValue.to_char("#,##0.00"); // BigNumber not accepted
// after
Value s = new Value(value.getName(), value.getNumber()).to_char("#,##0.00");
Defensive patterns

Strategy: type-guard

Validate before calling

if (value.getType() != Value.VALUE_TYPE_NUMBER && value.getType() != Value.VALUE_TYPE_INTEGER) { throw new IllegalArgumentException("NUM2STR requires Number or Integer"); }

Type guard

boolean num2strSafe(Value v) { return v.getType() == Value.VALUE_TYPE_NUMBER || v.getType() == Value.VALUE_TYPE_INTEGER; }

Try / catch

try { result = value.to_char(pattern); } catch (KettleValueException e) { result = value.isNumeric() ? String.valueOf(value.getNumber()) : value.getString(); }

Prevention

When it happens

Trigger: Calling value.to_char(pattern) (or to_char() with decimal/format arguments) on a Value whose type is String, Date, Boolean, or BigNumber rather than VALUE_TYPE_NUMBER or VALUE_TYPE_INTEGER.

Common situations: Formatting a number that was already converted to String by an earlier step; applying NUM2STR to dates (use the date TO_CHAR overload instead); BigNumber columns that this legacy path does not accept.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

        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 {
    if ( isNull() ) {
      setType( VALUE_TYPE_STRING );
    } else {

View on GitHub (pinned to f3058517a1)