pentaho/pentaho-kettle · error · KettleValueException
The 'combination1' function only works on numeric data
Error message
The 'combination1' function only works on numeric data
What it means
ValueDataUtil's 'combination1' helper (multiply-accumulate arithmetic A + B*C) computes with type-specific getters only for numeric value types (Number, Integer, String-as-numeric? no — String, Date, Boolean, BigNumber etc. that fall through). When metaA's type is not one of the handled numeric cases, the default branch throws this KettleValueException. Kettle/PDI calc functions require numeric input metadata; non-numeric types cannot participate in this arithmetic.
Solutions
- Change the Calculator step field type (or upstream Select Values / field metadata) to Number, Integer, or BigNumber before the combination1 calculation.
- Insert a 'String to number' conversion (Select Values metadata or a User Defined Java Expression / JavaScript step) for the offending field.
- If fields can be null or mixed, guard the calculation in a UDJC/Script step checking metaA.getType() before calling combination1.
Example fix
// before: Calculator 'A + B*C' with fieldA declared as String // after: in Select Values step preceding the Calculator, set fieldA Metadata -> Type: Number // then Calculator: combination1 with A=fieldA (Number), B=fieldB, C=fieldC
Defensive patterns
Strategy: type-guard
Validate before calling
// Java (PDI)
int t = metaA.getType();
if (t != ValueMetaInterface.TYPE_NUMBER && t != ValueMetaInterface.TYPE_INTEGER && t != ValueMetaInterface.TYPE_BIGNUMBER) {
throw new KettleValueException("combination1 requires numeric field A, got type " + t);
} Type guard
public static boolean isNumericMeta(ValueMetaInterface m) {
int t = m.getType();
return t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_INTEGER || t == ValueMetaInterface.TYPE_BIGNUMBER;
} Try / catch
try {
result = ValueDataUtil.combination1(metaA, dataA, metaB, dataB, metaC, dataC);
} catch (KettleValueException e) {
logError("combination1 needs numeric inputs: " + e.getMessage());
// route row to error handling stream or convert types and retry
} Prevention
- Always set explicit field types (Select Values metadata) before Calculator steps.
- Convert string fields from text/CSV inputs to numbers immediately after input steps.
- Enable row-level error handling on Calculator steps to catch type errors per row.
- Preview data types at each hop to catch silent re-typing.
When it happens
Trigger: Calling ValueDataUtil.combination1 (or the Calculator plugin's 'A + B * C' combination type) where the metadata type of the A field is not TYPE_NUMBER, TYPE_INTEGER, or TYPE_BIGNUMBER — e.g. a String, Date, or Boolean field is wired into the calculator step.
Common situations: Calculator step fed a CSV field read as String instead of Number; a type change upstream (e.g. a field switched from Integer to String) silently propagates; using a Date or Boolean output of another step in a combination formula.
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
- The 'abs' function only works on numeric data
- The 'ceil' function only works on numeric data
- The 'combination2' function only works on numeric data
- The 'floor' function only works on numeric data
- The 'remainder' function only works on numeric data
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/174462a620561fff.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java:1142
public static Object combination1( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB,
Object dataB, ValueMetaInterface metaC, Object dataC ) throws KettleValueException {
if ( dataA == null || dataB == null || dataC == null ) {
return null;
}
switch ( metaA.getType() ) {
case ValueMetaInterface.TYPE_NUMBER:
return new Double( metaA.getNumber( dataA ).doubleValue()
+ ( metaB.getNumber( dataB ).doubleValue() * metaC.getNumber( dataC ).doubleValue() ) );
case ValueMetaInterface.TYPE_INTEGER:
return new Long( metaA.getInteger( dataA ).longValue()
+ ( metaB.getInteger( dataB ).longValue() * metaC.getInteger( dataC ).longValue() ) );
case ValueMetaInterface.TYPE_BIGNUMBER:
return metaA.getBigNumber( dataA ).add(
multiplyBigDecimals( metaB.getBigNumber( dataB ), metaC.getBigNumber( dataC ), null ) );
default:
throw new KettleValueException( "The 'combination1' function only works on numeric data" );
}
}
/**
* SQRT( A*A + B*B )
*
* @param metaA
* @param dataA
* @param metaB
* @param dataB
* @return
* @throws KettleValueException
*/
public static Object combination2( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB, Object dataB ) throws KettleValueException {
if ( dataA == null || dataB == null ) {
return null;
}
View on GitHub (pinned to f3058517a1)