pentaho/pentaho-kettle · error · KettleException

The result of the filter expression must be a boolean and…

Error message

The result of the filter expression must be a boolean and we got back : {className}

What it means

Thrown by the Java Filter step's keep() method when the compiled filter expression evaluates to a non-Boolean value. The filter contract requires the Java expression to return a boolean so rows can be routed to the true/false branches.

Solutions

  1. Rewrite the filter expression so it evaluates to boolean (use comparisons and logical operators: ==, >, &&, ||).
  2. Do not use numeric 0/1 flags; use (value == 0) instead.
  3. Check for accidental casts or method calls returning Object; coerce explicitly, e.g. Boolean.parseBoolean(str).
  4. Read the className in the message — it names the actual returned type to fix.

Example fix

// before
expression: amount & 1
// after
expression: (amount & 1) == 1
Defensive patterns

Strategy: type-guard

Validate before calling

// Sanity-check the expression ends in a boolean comparison
String expr = meta.getCondition();
if (!expr.matches(".*(==|!=|>|<|>=|<=|&&|\|\|).*")) {
  throw new IllegalStateException("Filter expression must compare/return boolean: " + expr);
}

Type guard

boolean isBooleanResult(Object result) { return result instanceof Boolean; }

Try / catch

try { boolean keep = calcFields(row); } catch (KettleValueException e) { logError("Filter expression error: " + e.getMessage()); throw e; }

Prevention

When it happens

Trigger: data.expressionEvaluator.evaluate(argumentData) returns an object whose class is not Boolean — e.g. the expression ends with an assignment, a comparison wrapped by a method returning Object, or an expression like (a > b) ? 1 : 0 typed as int.

Common situations: Writing an expression whose result is int/String instead of boolean (e.g. using bitwise & instead of &&, or returning a numeric flag); a typo causing the evaluator's generic Object return path; copy-pasting a formula expression from the Formula step into Java Filter.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/javafilter/JavaFilter.java:205

        // Also create the argument data structure once...
        //
        data.argumentData = new Object[data.argumentIndexes.size()];
      }

      // This method can only accept the specified number of values...
      //
      for ( int x = 0; x < data.argumentIndexes.size(); x++ ) {
        int index = data.argumentIndexes.get( x );
        ValueMetaInterface outputValueMeta = data.outputRowMeta.getValueMeta( index );
        data.argumentData[x] = outputValueMeta.convertToNormalStorageType( r[index] );
      }

      Object formulaResult = data.expressionEvaluator.evaluate( data.argumentData );

      if ( formulaResult instanceof Boolean ) {
        return (Boolean) formulaResult;
      } else {
        throw new KettleException( "The result of the filter expression must be a boolean and we got back : "
          + formulaResult.getClass().getName() );
      }
    } catch ( Exception e ) {
      throw new KettleValueException( e );
    }
  }

  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {
    meta = (JavaFilterMeta) smi;
    data = (JavaFilterData) sdi;

    if ( super.init( smi, sdi ) ) {
      List<StreamInterface> targetStreams = meta.getStepIOMeta().getTargetStreams();
      data.trueStepname = targetStreams.get( 0 ).getStepname();
      data.falseStepname = targetStreams.get( 1 ).getStepname();

      if ( targetStreams.get( 0 ).getStepMeta() != null ^ targetStreams.get( 1 ).getStepMeta() != null ) {
        logError( BaseMessages.getString( PKG, "JavaFilter.Log.BothTrueAndFalseNeeded" ) );

View on GitHub (pinned to f3058517a1)