{"record":{"id":"379e2569c98ed1cb","repo":"pentaho/pentaho-kettle","slug":"function-mod-only-works-with-numeric-data","errorCode":null,"errorMessage":"Function MOD only works with numeric data","messagePattern":"Function MOD only works with numeric data","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/compatibility/Value.java","lineNumber":2648,"sourceCode":"    return mod( (double) arg );\n  }\n\n  public Value mod( byte arg ) throws KettleValueException {\n    return mod( (double) arg );\n  }\n\n  public Value mod( double arg0 ) throws KettleValueException {\n    if ( isNull() ) {\n      return this;\n    }\n\n    if ( isNumeric() ) {\n      double n1 = getNumber();\n      double n2 = arg0;\n\n      setValue( n1 - ( n2 * Math.floor( n1 / n2 ) ) );\n    } else {\n      throw new KettleValueException( \"Function MOD only works with numeric data\" );\n    }\n\n    return this;\n  }\n\n  // implement the NVL function, arguments in args[]\n  public Value nvl( Value alt ) {\n    if ( isNull() ) {\n      setValue( alt );\n    }\n    return this;\n  }\n\n  // implement the POWER function, arguments in args[]\n  public Value power( BigDecimal arg ) throws KettleValueException {\n    return power( new Value( \"tmp\", arg ) );\n  }\n","sourceCodeStart":2630,"sourceCodeEnd":2666,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/compatibility/Value.java#L2630-L2666","documentation":"Thrown by Value.mod() in Pentaho Kettle's legacy compatibility Value class when the MOD function is called on a value whose type is not numeric. The class deliberately guards each mathematical function with an isNumeric() check and throws KettleValueException instead of silently producing garbage. The value's type must be Number or Integer (or BigNumber) before MOD is applied.","triggerScenarios":"Calling value.mod(otherValue) (or the MOD function in a Kettle formula/script step) when the receiving Value has a String, Date, Boolean, or Binary type rather than a numeric type.","commonSituations":"A CSV/text input field was auto-detected or typed as String but the transformation applies MOD; a field's metadata was changed in a Select Values step; users pass date or boolean columns into a calculator formula.","solutions":["Check the value's type before calling mod(): only call it when value.isNumeric() is true.","Convert the value to numeric first, e.g. value.convertToNumber() or read the field with the correct Number/Integer type in the input step.","Fix the field metadata in the input or a 'Select values' step so the column is typed as Number/Integer.","Wrap the call in try/catch for KettleValueException and handle the non-numeric branch explicitly."],"exampleFix":"// before\nValue result = value.mod(divisor); // throws if value is a String\n// after\nif (value.isNumeric()) {\n  Value result = value.mod(divisor);\n} else {\n  Value num = new Value(value.getName(), value.getNumber()); // or convert type upstream\n}","handlingStrategy":"type-guard","validationCode":"if (!value.isNumeric()) { throw new IllegalArgumentException(value.getName() + \" is not numeric; cannot MOD\"); }","typeGuard":"boolean modSafe(Value v) { return v != null && (v.isNull() || v.isNumeric()); }","tryCatchPattern":"try { result = value.mod(divisor); } catch (KettleValueException e) { log.error(\"MOD on non-numeric: \" + e.getMessage()); result = null; }","preventionTips":["Always type numeric columns as Number/Integer in input steps","Call isNumeric() before any math function on Value","Keep transformations' field metadata consistent end-to-end"],"tags":["kettle","type-mismatch","numeric"],"backgroundTag":"type-mismatch","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}