pentaho/pentaho-kettle · error · KettleValueException
The value: [ ] is a negative number. The 'sqrt' function…
Error message
The value: [${num}] is a negative number. The 'sqrt' function only works with non-negative numbers. What it means
ValueDataUtil.sqrt() computes the square root of a numeric field (Number, Integer, or BigNumber). When the input value is negative, Math.sqrt would yield NaN, so Kettle throws KettleValueException instead of returning a silently wrong result. The exception message embeds the offending value so the failing row/data can be identified.
Solutions
- Check the input data: find rows feeding the SQRT calculation where the value is negative and fix them at the source
- Guard the expression: compute SQRT only when value >= 0, e.g. use an IF/ternary in the Calculator or Formula step: value < 0 ? null : SQRT(value)
- Take ABS() first if sign is irrelevant: SQRT(ABS(value))
- Apply the square root to a squared quantity (variance/stddev pattern) so the operand is always non-negative
Example fix
// before (Calculator/UDF via ValueDataUtil)
Object r = ValueDataUtil.sqrt(metaA, dataA); // throws if dataA < 0
// after
Object r = (metaA.getNumber(dataA) >= 0)
? ValueDataUtil.sqrt(metaA, dataA)
: null; Defensive patterns
Strategy: validation
Validate before calling
if (metaA != null && metaA.getType() == ValueMetaInterface.TYPE_NUMBER && metaA.getNumber(dataA) != null && metaA.getNumber(dataA) >= 0) { result = ValueDataUtil.sqrt(metaA, dataA); } else { result = null; /* or log & skip row */ } Type guard
boolean isNonNegativeNumeric(ValueMetaInterface meta, Object data) {
if (meta == null || data == null) return false;
int t = meta.getType();
if (t != ValueMetaInterface.TYPE_NUMBER && t != ValueMetaInterface.TYPE_INTEGER && t != ValueMetaInterface.TYPE_BIGNUMBER) return false;
Number n = (Number) meta.convertData(data);
return n.doubleValue() >= 0;
} Try / catch
try {
result = ValueDataUtil.sqrt(metaA, dataA);
} catch (KettleValueException e) {
logError("SQRT of negative value in row " + getRowNr() + ": " + e.getMessage());
putRow(outputRowMeta, RowDataUtil.addValueData(inputRow, outputRowMeta.size(), null)); // null result, keep pipeline flowing
} Prevention
- Clamp or ABS() any expression that feeds SQRT and can go negative (differences, deltas)
- Prefer computing sqrt of squared quantities (variance) rather than raw signed data
- Add a Filter rows / validation step before the Calculator to catch negative values early
- Set the Calculator's error handling to route bad rows to a separate stream
When it happens
Trigger: Calling ValueDataUtil.sqrt(metaA, dataA) (or a Calculator step / formula using the SQRT function) where metaA.getType() is TYPE_NUMBER and dataA is a negative double (num < 0).
Common situations: Calculator step computing sqrt of a difference that can go negative (e.g. variance from mismatched column order), formula fields over raw measurements that can be negative, importing negative sensor values, sign errors in upstream transformations.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Calculator.Error.NoNameField
- Calculator.Error.UnableFindField
- Calculator.ErrorInStepRunning
- Calculator.Log.NoType + ( i + 1 ) + " : " + fieldName + " =…
- Calculator.Log.UnknownCalculationType + fn.getCalcType()
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/5355cfddd2bbc28d.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java:931
}
}
return MathContext.UNLIMITED;
}
public static Object sqrt( ValueMetaInterface metaA, Object dataA ) throws KettleValueException {
if ( dataA == null ) {
return null;
}
Double num;
switch ( metaA.getType() ) {
case ValueMetaInterface.TYPE_NUMBER:
num = metaA.getNumber( dataA );
if ( num >= 0 ) {
return new Double( Math.sqrt( num.doubleValue() ) );
}
throw new KettleValueException( valueNotNegative( num ) );
case ValueMetaInterface.TYPE_INTEGER:
num = metaA.getNumber( dataA );
if ( num >= 0 ) {
return new Long( Math.round( Math.sqrt( num.doubleValue() ) ) );
}
throw new KettleValueException( valueNotNegative( num ) );
case ValueMetaInterface.TYPE_BIGNUMBER:
num = metaA.getNumber( dataA );
if ( num >= 0 ) {
return BigDecimal.valueOf( Math.sqrt( num.doubleValue() ) );
}
throw new KettleValueException( valueNotNegative( num ) );
default:
throw new KettleValueException( "The 'sqrt' function only works on numeric data." );
}
}
View on GitHub (pinned to f3058517a1)