pentaho/pentaho-kettle · error · KettleValueException

throw new KettleValueException( e );

Error message

throw new KettleValueException( e );

What it means

Catch-all wrapper in Formula.calcFields(): any Throwable escaping formula setup, evaluation, or result conversion is rethrown as a KettleValueException with the original as cause. The 'message' shown is just the wrap site; the real cause is in getCause().

Solutions

  1. Log and inspect the 'Caused by' of the KettleValueException for the real error.
  2. Validate the formula expression syntax in the formula editor before running.
  3. Ensure all pentaho-reporting-libformula dependencies are on the classpath.
  4. Check the specific result type handling if the formula output type changed recently.

Example fix

// before
String f = "SUM([a"
// after
String f = "SUM([a])"; // balanced, parseable formula
Defensive patterns

Strategy: try-catch

Try / catch

try { output = calcFields(row); } catch (KettleValueException e) { Throwable root = e; while (root.getCause() != null) root = root.getCause(); log.error("Formula failure root cause: " + root.getMessage(), root); throw e; }

Prevention

When it happens

Trigger: Any runtime failure inside calcFields not already thrown explicitly — e.g. formula engine parse errors, class loading issues for the reporting formula library, unexpected result types in getReturnValue().

Common situations: Malformed formula syntax accepted at design time but failing per row; missing pentaho-reporting formula engine jars at runtime; type conversion failure in getReturnValue().

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/3077712b76fbed17. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/formula/Formula.java:196

              data.returnType[i] = FormulaData.RETURN_TYPE_BOOLEAN;
              if ( fn.getValueType() != ValueMetaInterface.TYPE_BOOLEAN ) {
                throw new KettleValueException( "Please specify a Boolean type for field ["
                  + fn.getFieldName() + "] as a result of formula [" + fn.getFormula() + "]" );
              }
            } else {
              data.returnType[i] = FormulaData.RETURN_TYPE_STRING;
              fn.setNeedDataConversion( fn.getValueType() != ValueMetaInterface.TYPE_STRING );
            }
          }

          int realIndex = ( data.replaceIndex[i] < 0 ) ? tempIndex++ : data.replaceIndex[i];
          outputRowData[realIndex] = getReturnValue( formulaResult, data.returnType[i], realIndex, fn );
        }
      }

      return outputRowData;
    } catch ( Throwable e ) {
      throw new KettleValueException( e );
    }
  }

  protected Object getReturnValue( Object formulaResult, int returnType, int realIndex, FormulaMetaFunction fn )
    throws KettleException {
    if ( formulaResult == null ) {
      return null;
    }
    Object value = null;
    switch ( returnType ) {
      case FormulaData.RETURN_TYPE_STRING:
        if ( fn.isNeedDataConversion() ) {
          value = convertDataToTargetValueMeta( realIndex, formulaResult );
        } else {
          value = formulaResult.toString();
        }
        break;
      case FormulaData.RETURN_TYPE_NUMBER:

View on GitHub (pinned to f3058517a1)