pentaho/pentaho-kettle · error · KettleValueException
<toString()> : couldn't convert String to number …
Error message
<toString()> : couldn't convert String to number : non-numeric character found at position <parsePosition.getIndex() + 1> for value [<string>]
What it means
Thrown by ValueMetaBase.convertStringToInteger (Long path) when DecimalFormat.parse(string, parsePosition) stops before consuming the whole string, i.e. a non-numeric character appears after the numeric prefix. The message gives the 1-based position via parsePosition.getIndex() + 1 and the offending value.
Solutions
- Pre-validate the string matches ^[+-]?\\d+$ (after removing expected separators) before conversion
- Set an appropriate mask with setConversionMask or convert the field to TYPE_NUMBER if it holds decimals
- Trim whitespace/non-breaking spaces and strip units/symbols first
- Use transformation error handling to route offending rows aside and inspect them
Example fix
// before
Long n = valueMeta.getInteger("1 234 kg"); // throws: non-numeric char at position 7
// after
String cleaned = raw.replaceAll("\\D", "");
Long n = valueMeta.getInteger(cleaned); Defensive patterns
Strategy: validation
Validate before calling
static boolean isCleanInteger(String s) {
if (s == null) return false;
String t = s.trim().replace("\u00A0", "");
return t.matches("[+-]?\\d+");
} Type guard
static boolean parsesFullyAsLong(java.text.DecimalFormat fmt, String s) {
java.text.ParsePosition pos = new java.text.ParsePosition(0);
Number n = fmt.parse(s, pos);
return n != null && pos.getIndex() == s.trim().length();
} Try / catch
try {
Long n = valueMeta.getInteger(raw);
} catch (KettleValueException e) {
log.error("Bad integer '" + raw + "' at char " + e.getMessage());
routeToErrorRow(raw);
return null;
} Prevention
- Route decimal-looking data to Number fields, not Integer
- Strip units, percent signs, and non-breaking spaces before parsing
- Pre-validate with DecimalFormat + ParsePosition full-consumption check
- Configure transformation error handling with a rejected-rows stream
When it happens
Trigger: Calling getInteger()/convertStringToInteger() with strings like '12a3', '1 000,5x', or values with trailing characters that don't match the integer format mask; also when decimal separators appear where the mask expects an integer.
Common situations: Decimal values ('12.5') fed into an Integer field; trailing percent signs, units, or footnotes; thousand separators not matching the configured mask; Excel exports with invisible trailing characters.
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 Long to String
- <toString()> : couldn't convert String to number with…
- AnalyticQueryMeta.Exception.UnableToLoadStepInfoFromXML
- Could not convert the given String :
- e.toString()
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/74573d37e1d86fa5.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/value/ValueMetaBase.java:1341
protected synchronized Long convertStringToInteger( String string ) throws KettleValueException {
string = Const.trimToType( string, getTrimType() ); // see if trimming needs
// to be performed before
// conversion
if ( Utils.isEmpty( string ) ) {
return null;
}
try {
Number number;
if ( lenientStringToNumber ) {
number = getDecimalFormat( false ).parse( string );
} else {
ParsePosition parsePosition = new ParsePosition( 0 );
number = getDecimalFormat( false ).parse( string, parsePosition );
if ( parsePosition.getIndex() < string.length() ) {
throw new KettleValueException( toString()
+ " : couldn't convert String to number : non-numeric character found at position "
+ ( parsePosition.getIndex() + 1 ) + " for value [" + string + "]" );
}
}
if ( number instanceof Double && ( number.doubleValue() < Long.MIN_VALUE
|| number.doubleValue() > Long.MAX_VALUE ) ) {
log.logBasic( "Value [" + string + "] is out of range for Integer." );
if ( !ignoreOutOfRange ) {
throw new KettleValueException( toString()
+ " : couldn't convert String to Integer : value Out of Range [" + string
+ "]. Change the destination data type or round to the nearest value possible for Integer by setting "
+ "property KETTLE_IGNORE_OUT_OF_RANGE_EXCEPTION to \"Y\". " );
}
}
return new Long( number.longValue() );
} catch ( Exception e ) {View on GitHub (pinned to f3058517a1)