pentaho/pentaho-kettle · error · org.pentaho.di.core.exception.KettleValueException
The 'divide' function only works on numeric data.
Error message
The 'divide' function only works on numeric data.
What it means
This divide() overload (no VariableSpace) supports only TYPE_NUMBER, TYPE_INTEGER, and TYPE_BIGNUMBER; any other value type hits the default branch and throws KettleValueException. Division has no string/boolean fallback, so non-numeric input always fails.
Solutions
- Convert both fields to numeric types (Select values / Calculator) before dividing
- Correct the stream's field type metadata so it is Number/Integer/BigDecimal
- If dividing strings that contain numbers, parse them explicitly first (Str2Num)
- Verify upstream steps preserve numeric types
Example fix
// before
Object r = ValueDataUtil.divide(metaStr, "10", metaNum, 2.0); // String input
// after
ValueMetaInterface numMeta = new ValueMetaNumber("a_num");
Object a = numMeta.convertData(metaStr, "10");
Object r = ValueDataUtil.divide(numMeta, a, metaNum, 2.0); Defensive patterns
Strategy: validation
Validate before calling
// Java: both operands must be numeric for divide
for (ValueMetaInterface m : new ValueMetaInterface[]{metaA, metaB}) {
int t = m.getType();
if (!(t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_INTEGER
|| t == ValueMetaInterface.TYPE_BIGNUMBER)) {
throw new IllegalArgumentException("divide needs numeric input, got " + m.getTypeDesc());
}
} Type guard
boolean isDivideSafe(ValueMetaInterface m) {
int t = m.getType();
return t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_INTEGER
|| t == ValueMetaInterface.TYPE_BIGNUMBER;
} Try / catch
try {
result = ValueDataUtil.divide(metaA, dataA, metaB, dataB);
} catch (KettleValueException e) {
log.error("divide requires numeric operands: " + metaA.getTypeDesc() + "/" + metaB.getTypeDesc());
throw e;
} Prevention
- Convert numeric-looking Strings with Str2Num before division
- Keep stream field types consistent across transformation revisions
- Guard against divide-by-zero separately after type checks
- Type-check inputs in tests for any Calculator division step
When it happens
Trigger: Calling ValueDataUtil.divide(metaA, dataA, metaB, dataB) where either meta is Boolean, String, Date, Binary, or unspecified — the switch has no matching case.
Common situations: Calculator 'A/B' step receiving a String-typed field from CSV; a rate/percent calculation where the numerator was changed to Boolean; type drift after upstream refactoring.
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
- Division can only be done with numeric data!
- The 'multiply' function only works on numeric data…
- The 'plus' function only works on numeric data and Strings.
- BaseStep.SafeMode.Exception.MixingTypes
- DynamicSQLRow.Exception.TemplateReturnDataTypeError
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/7044c28aea9a7341.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java:842
return s.toString();
}
@Deprecated
public static Object divide( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB, Object dataB ) throws KettleValueException {
if ( dataA == null || dataB == null ) {
return null;
}
switch ( metaA.getType() ) {
case ValueMetaInterface.TYPE_NUMBER:
return divideDoubles( metaA.getNumber( dataA ), metaB.getNumber( dataB ) );
case ValueMetaInterface.TYPE_INTEGER:
return divideLongs( metaA.getInteger( dataA ), metaB.getInteger( dataB ) );
case ValueMetaInterface.TYPE_BIGNUMBER:
return divideBigDecimals( metaA.getBigNumber( dataA ), metaB.getBigNumber( dataB ), (MathContext) null );
default:
throw new KettleValueException( "The 'divide' function only works on numeric data." );
}
}
public static Object divide( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB, Object dataB, VariableSpace space ) throws KettleValueException {
if ( dataA == null || dataB == null ) {
return null;
}
switch ( metaA.getType() ) {
case ValueMetaInterface.TYPE_NUMBER:
return divideDoubles( metaA.getNumber( dataA ), metaB.getNumber( dataB ) );
case ValueMetaInterface.TYPE_INTEGER:
return divideLongs( metaA.getInteger( dataA ), metaB.getInteger( dataB ) );
case ValueMetaInterface.TYPE_BIGNUMBER:
return divideBigDecimals( metaA.getBigNumber( dataA ), metaB.getBigNumber( dataB ), space );
default:
throw new KettleValueException( "The 'divide' function only works on numeric data." );View on GitHub (pinned to f3058517a1)