pentaho/pentaho-kettle · error · KettleValueException

<toString()> : couldn't convert String to number

Error message

<toString()> : couldn't convert String to number 

What it means

Generic wrapper thrown by ValueMetaBase.convertStringToNumber when any exception occurs during string-to-Number conversion outside the specific 'unexpected character' case — e.g. ParseException from DecimalFormat.parse, null format, or numeric overflow while constructing the Double. The message names the value meta.

Solutions

  1. Validate/clean the input string is numeric before conversion
  2. Fix the conversion mask / locale pairing with setConversionMask and setConversionLocale
  3. Log the wrapped cause exception (getCause()) to identify the concrete failure
  4. Catch KettleValueException and route bad rows to an error handling stream

Example fix

// before
valueMeta.setConversionMask("0.00"); // data uses ',' decimal separator, locale uses '.'
// after
valueMeta.setConversionMask("0,00");
valueMeta.setConversionLocale(new Locale("de", "DE"));
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean isNumeric(String s) {
  return s != null && s.trim().matches("[+-]?(\\d+([.,]\\d+)?|[.,]\\d+)");
}

Try / catch

try {
  Number n = valueMeta.getNumber(raw);
} catch (KettleValueException e) {
  Throwable cause = e.getCause(); // real parse error
  log.error("String->Number failed for '" + raw + "': " + cause, cause);
  return null;
}

Prevention

When it happens

Trigger: Calling getNumber()/convertStringToNumber() where getDecimalFormat throws (invalid mask for the locale), the string is unparseable and hits the catch-all, or an internal error occurs before returning the Double.

Common situations: Conversion masks incompatible with the configured locale; strings like '--5' or completely non-numeric garbage; regional settings mismatch between data source and transformation.

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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:1038

      DecimalFormat format = getDecimalFormat( false );
      Number number;
      if ( lenientStringToNumber ) {
        number = format.parse( string );
      } else {
        ParsePosition parsePosition = new ParsePosition( 0 );
        number = format.parse( string, parsePosition );

        if ( parsePosition.getIndex() < string.length() ) {
          throw new KettleValueException( toString()
              + " : couldn't convert String to number with " + ( ( getFormatMask() == null ) ? "empty format" : "format [" + getFormatMask() + "]" ) +  ": unexpected character found at position "
              + ( parsePosition.getErrorIndex() + 1 ) + " for value [" + string + "]" );
        }

      }

      return new Double( number.doubleValue() );
    } catch ( Exception e ) {
      throw new KettleValueException( toString() + " : couldn't convert String to number ", e );
    }
  }

  @Override
  public synchronized SimpleDateFormat getDateFormat() {
    return getDateFormat( getType() );
  }

  private synchronized SimpleDateFormat getDateFormat( int valueMetaType ) {
    // If we have a Date that is represented as a String
    // In that case we can set the format of the original Date on the String
    // value metadata in the form of a conversion metadata object.
    // That way, we can always convert from Date to String and back without a
    // problem, no matter how complex the format was.
    // As such, we should return the date SimpleDateFormat of the conversion
    // metadata.
    //
    if ( conversionMetadata != null ) {

View on GitHub (pinned to f3058517a1)