{"record":{"id":"d19f5ea6dbfdcf0c","repo":"pentaho/pentaho-kettle","slug":"function-floor-only-works-with-a-number","errorCode":null,"errorMessage":"Function FLOOR only works with a number","messagePattern":"Function FLOOR only works with a number","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/compatibility/Value.java","lineNumber":2484,"sourceCode":"\n    if ( isNumeric() ) {\n      setValue( Math.exp( getNumber() ) );\n    } else {\n      throw new KettleValueException( \"Function EXP only works with a number\" );\n    }\n    return this;\n  }\n\n  // implement the FLOOR function, arguments in args[]\n  public Value floor() throws KettleValueException {\n    if ( isNull() ) {\n      return this;\n    }\n\n    if ( isNumeric() ) {\n      setValue( Math.floor( getNumber() ) );\n    } else {\n      throw new KettleValueException( \"Function FLOOR only works with a number\" );\n    }\n    return this;\n  }\n\n  // implement the INITCAP function, arguments in args[]\n  public Value initcap() {\n    if ( isNull() ) {\n      return this;\n    }\n\n    if ( getString() == null ) {\n      setNull();\n    } else {\n      setValue( Const.initCap( getString() ) );\n    }\n    return this;\n  }\n","sourceCodeStart":2466,"sourceCodeEnd":2502,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/compatibility/Value.java#L2466-L2502","documentation":"The floor() method of Kettle's legacy Value class rounds the value down using Math.floor. It throws this KettleValueException when the Value is not numeric, because Math.floor requires a double. The legacy compatibility Value class validates operand type at runtime for each math function.","triggerScenarios":"Calling Value.floor() on a Value typed as String, Date or Boolean - e.g. flooring a value taken from a text column without conversion.","commonSituations":"Integer partitioning of String-typed measurements from CSV/Excel; Boolean fields accidentally routed into numeric rounding logic.","solutions":["Convert the Value to Number before calling floor() (setType(VALUE_TYPE_NUMBER) or a Select values type conversion)","Fix the source step so the field is numeric end to end","Guard with isNumeric() and convert or branch explicitly"],"exampleFix":"// before\nValue rounded = value.floor(); // value is a String\n// after\nif (!value.isNumeric()) {\n  value.setType(Value.VALUE_TYPE_NUMBER);\n}\nValue rounded = value.floor();","handlingStrategy":"type-guard","validationCode":"if (value == null || !value.isNumeric()) {\n  throw new IllegalArgumentException(\"FLOOR requires a numeric value, got type \" + (value == null ? \"null\" : value.getType()));\n}","typeGuard":"boolean isNumericValue(Value v) { return v != null && v.isNumeric(); }","tryCatchPattern":"try {\n  result = value.floor();\n} catch (KettleValueException e) {\n  value.setType(Value.VALUE_TYPE_NUMBER);\n  result = value.floor();\n}","preventionTips":["Declare measurement columns as Number in the input step","Insert explicit String-to-Number conversion before rounding","Precondition-check with isNumeric() before calling floor()","Audit transformations for numeric logic fed by text-detected columns"],"tags":["kettle","numeric-type","math-function","runtime-type-check"],"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"}