{"record":{"id":"affc92d4820ee27a","repo":"pentaho/pentaho-kettle","slug":"function-ceil-only-works-with-a-number","errorCode":null,"errorMessage":"Function CEIL only works with a number","messagePattern":"Function CEIL 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":2442,"sourceCode":"\n    if ( isNumeric() ) {\n      setValue( Math.atan2( getNumber(), arg0 ) );\n    } else {\n      throw new KettleValueException( \"Function ATAN2 only works with numbers\" );\n    }\n    return this;\n  }\n\n  // implement the CEIL function, arguments in args[]\n  public Value ceil() throws KettleValueException {\n    if ( isNull() ) {\n      return this;\n    }\n\n    if ( isNumeric() ) {\n      setValue( Math.ceil( getNumber() ) );\n    } else {\n      throw new KettleValueException( \"Function CEIL only works with a number\" );\n    }\n    return this;\n  }\n\n  // implement the COS function, arguments in args[]\n  public Value cos() throws KettleValueException {\n    if ( isNull() ) {\n      return this;\n    }\n\n    if ( isNumeric() ) {\n      setValue( Math.cos( getNumber() ) );\n    } else {\n      throw new KettleValueException( \"Function COS only works with a number\" );\n    }\n    return this;\n  }\n","sourceCodeStart":2424,"sourceCodeEnd":2460,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/compatibility/Value.java#L2424-L2460","documentation":"The ceil() method of Kettle's legacy Value class rounds the value up to the nearest integer using Math.ceil. It throws this KettleValueException when the Value is not numeric, since Math.ceil accepts only a double. The legacy Value class enforces operand types at runtime.","triggerScenarios":"Calling Value.ceil() on a Value of type String, Date, or Boolean - e.g. rounding a value that arrived from a text input without numeric conversion.","commonSituations":"Rounding price/quantity fields parsed from CSV as String; Boolean or flag fields accidentally passed into rounding logic; schema drift after changing an input file format.","solutions":["Convert the Value to a numeric type before calling ceil()","Correct the producing step so the field is Number-typed","Check isNumeric() first and convert or handle non-numeric values explicitly"],"exampleFix":"// before\nValue rounded = value.ceil(); // value is a String\n// after\nif (!value.isNumeric()) {\n  value.setType(Value.VALUE_TYPE_NUMBER);\n}\nValue rounded = value.ceil();","handlingStrategy":"type-guard","validationCode":"if (value == null || !value.isNumeric()) {\n  throw new IllegalArgumentException(\"CEIL 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.ceil();\n} catch (KettleValueException e) {\n  value.setType(Value.VALUE_TYPE_NUMBER);\n  result = value.ceil();\n}","preventionTips":["Round only fields confirmed numeric by the input step","Convert price/quantity columns parsed from text to Number first","Call isNumeric() before rounding functions","Watch for Boolean flags accidentally wired into rounding logic"],"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"}