{"record":{"id":"131afaacdcd02af3","repo":"pentaho/pentaho-kettle","slug":"function-tan-only-works-on-a-number","errorCode":null,"errorMessage":"Function TAN only works on a number","messagePattern":"Function TAN only works on a number","errorType":"exception","errorClass":"KettleValueException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/compatibility/Value.java","lineNumber":3022,"sourceCode":"  }\n\n  // implement the SYSDATE function, arguments in args[]\n  public Value sysdate() {\n    setValue( Calendar.getInstance().getTime() );\n\n    return this;\n  }\n\n  // implement the TAN function, arguments in args[]\n  public Value tan() throws KettleValueException {\n    if ( isNull() ) {\n      return this;\n    }\n\n    if ( isNumeric() ) {\n      setValue( Math.tan( getNumber() ) );\n    } else {\n      throw new KettleValueException( \"Function TAN only works on a number\" );\n    }\n\n    return this;\n  }\n\n  // implement the TO_CHAR function, arguments in args[]\n  // number: NUM2STR( 123.456 ) : default format\n  // number: NUM2STR( 123.456, '###,##0.000') : format\n  // number: NUM2STR( 123.456, '###,##0.000', '.') : grouping\n  // number: NUM2STR( 123.456, '###,##0.000', '.', ',') : decimal\n  // number: NUM2STR( 123.456, '###,##0.000', '.', ',', '?') : currency\n\n  public Value num2str() throws KettleValueException {\n    return num2str( null, null, null, null );\n  }\n\n  public Value num2str( String format ) throws KettleValueException {\n    return num2str( format, null, null, null );","sourceCodeStart":3004,"sourceCodeEnd":3040,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/compatibility/Value.java#L3004-L3040","documentation":"Thrown by Value.tan() when the value is not numeric. TAN computes Math.tan(getNumber()) behind an isNumeric() guard; String, Date, Boolean, and Binary values raise KettleValueException. Nulls return early with no error.","triggerScenarios":"Calling value.tan() on a non-numeric Value, most often an angle stored as String.","commonSituations":"Trigonometric transformations on text-file columns; angle data ingested as strings; using TAN on mis-typed field metadata.","solutions":["Guard with value.isNumeric() before calling tan().","Convert the angle field to Number before applying TAN.","Correct the field type in the input step or a 'Select values' step.","Catch KettleValueException and route bad rows to error handling."],"exampleFix":"// before\nValue t = value.tan(); // throws for String-typed value\n// after\nValue t = value.isNumeric() ? value.tan() : new Value(value.getName(), Math.tan(Double.parseDouble(value.getString())));","handlingStrategy":"type-guard","validationCode":"if (!value.isNumeric()) { throw new IllegalArgumentException(\"TAN requires a numeric angle\"); }","typeGuard":"boolean tanSafe(Value v) { return v != null && v.isNumeric(); }","tryCatchPattern":"try { result = value.tan(); } catch (KettleValueException e) { result = null; }","preventionTips":["Convert angle text to Number before TAN","Maintain numeric metadata across steps","Handle isNull() separately — nulls return unchanged"],"tags":["kettle","type-mismatch","trigonometry"],"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"}