{"record":{"id":"7044c28aea9a7341","repo":"pentaho/pentaho-kettle","slug":"the-divide-function-only-works-on-numeric-data","errorCode":null,"errorMessage":"The 'divide' function only works on numeric data.","messagePattern":"The 'divide' function only works on numeric data\\.","errorType":"exception","errorClass":"org.pentaho.di.core.exception.KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java","lineNumber":842,"sourceCode":"    return s.toString();\n  }\n\n  @Deprecated\n  public static Object divide( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB, Object dataB ) throws KettleValueException {\n    if ( dataA == null || dataB == null ) {\n      return null;\n    }\n\n    switch ( metaA.getType() ) {\n      case ValueMetaInterface.TYPE_NUMBER:\n        return divideDoubles( metaA.getNumber( dataA ), metaB.getNumber( dataB ) );\n      case ValueMetaInterface.TYPE_INTEGER:\n        return divideLongs( metaA.getInteger( dataA ), metaB.getInteger( dataB ) );\n      case ValueMetaInterface.TYPE_BIGNUMBER:\n        return divideBigDecimals( metaA.getBigNumber( dataA ), metaB.getBigNumber( dataB ), (MathContext) null );\n\n      default:\n        throw new KettleValueException( \"The 'divide' function only works on numeric data.\" );\n    }\n  }\n\n  public static Object divide( ValueMetaInterface metaA, Object dataA, ValueMetaInterface metaB, Object dataB, VariableSpace space ) throws KettleValueException {\n    if ( dataA == null || dataB == null ) {\n      return null;\n    }\n\n    switch ( metaA.getType() ) {\n      case ValueMetaInterface.TYPE_NUMBER:\n        return divideDoubles( metaA.getNumber( dataA ), metaB.getNumber( dataB ) );\n      case ValueMetaInterface.TYPE_INTEGER:\n        return divideLongs( metaA.getInteger( dataA ), metaB.getInteger( dataB ) );\n      case ValueMetaInterface.TYPE_BIGNUMBER:\n        return divideBigDecimals( metaA.getBigNumber( dataA ), metaB.getBigNumber( dataB ), space );\n\n      default:\n        throw new KettleValueException( \"The 'divide' function only works on numeric data.\" );","sourceCodeStart":824,"sourceCodeEnd":860,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/row/ValueDataUtil.java#L824-L860","documentation":"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.","triggerScenarios":"Calling ValueDataUtil.divide(metaA, dataA, metaB, dataB) where either meta is Boolean, String, Date, Binary, or unspecified — the switch has no matching case.","commonSituations":"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.","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"],"exampleFix":"// before\nObject r = ValueDataUtil.divide(metaStr, \"10\", metaNum, 2.0); // String input\n// after\nValueMetaInterface numMeta = new ValueMetaNumber(\"a_num\");\nObject a = numMeta.convertData(metaStr, \"10\");\nObject r = ValueDataUtil.divide(numMeta, a, metaNum, 2.0);","handlingStrategy":"validation","validationCode":"// Java: both operands must be numeric for divide\nfor (ValueMetaInterface m : new ValueMetaInterface[]{metaA, metaB}) {\n  int t = m.getType();\n  if (!(t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_INTEGER\n     || t == ValueMetaInterface.TYPE_BIGNUMBER)) {\n    throw new IllegalArgumentException(\"divide needs numeric input, got \" + m.getTypeDesc());\n  }\n}","typeGuard":"boolean isDivideSafe(ValueMetaInterface m) {\n  int t = m.getType();\n  return t == ValueMetaInterface.TYPE_NUMBER || t == ValueMetaInterface.TYPE_INTEGER\n      || t == ValueMetaInterface.TYPE_BIGNUMBER;\n}","tryCatchPattern":"try {\n  result = ValueDataUtil.divide(metaA, dataA, metaB, dataB);\n} catch (KettleValueException e) {\n  log.error(\"divide requires numeric operands: \" + metaA.getTypeDesc() + \"/\" + metaB.getTypeDesc());\n  throw e;\n}","preventionTips":["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"],"tags":["type-mismatch","arithmetic","division","kettle"],"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"}