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
- Validate/clean the input string is numeric before conversion
- Fix the conversion mask / locale pairing with setConversionMask and setConversionLocale
- Log the wrapped cause exception (getCause()) to identify the concrete failure
- 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
- Inspect getCause() to find the concrete parse failure
- Set conversion mask AND locale together so they agree
- Clean upstream data (strip symbols, normalize separators) at ingestion
- Use row-level error handling rather than failing whole transformations
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
- <toString()> : couldn't convert String to number with…
- AnalyticQueryMeta.Exception.UnableToLoadStepInfoFromXML
- Could not convert the given String :
- CsvInput.Log.Error.ErrorConvertingLine (with e.toString())
- Error_0001
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)