flowable/flowable-engine · error · FlowableException

condition expression returns non-Boolean

Error message

condition expression returns non-Boolean: <result> (<class name>)

What it means

RuleExpressionCondition.evaluate requires the input condition expression to produce a Boolean so the rule engine can compare it against the input entry. If the JUEL expression returns any non-Boolean value (String, Integer, etc.), Flowable throws this exception including the value and its class name. The decision table author must make the condition expression a comparison/logical expression.

Solutions

  1. Rewrite the input expression as a Boolean comparison, e.g. ${amount > 100} instead of ${amount}.
  2. Check that any custom EL function used in the condition returns Boolean, not String/Number.
  3. If the expression evaluates a String, wrap it in a comparison or a Boolean-returning helper function.
  4. Validate the exported DMN XML: inputExpression expressionLanguage JUEL entries should end in boolean predicates.
  5. Log result.getClass() at the call site to identify which expression returns the wrong type (the message already embeds value + class name).

Example fix

// before (DMN input expression)
${customerLevel}            // returns String "gold"
// after
${customerLevel == 'gold'}  // returns Boolean
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = evaluateRaw(expr); if (!(v instanceof Boolean)) throw new IllegalStateException("condition not boolean: " + v.getClass());

Type guard

boolean conditionYieldsBoolean(Object result) {
    return result != null && result instanceof Boolean;
}

Try / catch

try {
    Boolean hit = condition.evaluate(container);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("condition expression returns non-Boolean")) {
        log.error("Fix DMN input expression: {}", e.getMessage());
    }
}

Prevention

When it happens

Trigger: executeInputExpression calls evaluate and the expression returns e.g. a String ('yes'), an Integer, or a bare variable reference like ${customerLevel} instead of a comparison like ${customerLevel == 'gold'}.

Common situations: Decision table input expression written as a bare variable or literal rather than a boolean comparison; EL function returning a non-Boolean; spreadsheet/DMN export producing expressions of the wrong shape.

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 flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/a6821a84c6941fe9. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/el/RuleExpressionCondition.java:48

    protected Expression expression;

    public RuleExpressionCondition(Expression expression) {
        this.expression = expression;
    }

    public boolean evaluate(Map<String, Object> variables, ELExecutionContext executionContext) {
        VariableContainerWrapper variableContainer = new VariableContainerWrapper(variables);
        variableContainer.setInstanceId(executionContext.getInstanceId());
        variableContainer.setScopeType(executionContext.getScopeType());
        variableContainer.setTenantId(executionContext.getTenantId());

        Object result = expression.getValue(variableContainer);

        if (result == null) {
            throw new FlowableException("condition expression returns null");
        }
        if (!(result instanceof Boolean)) {
            throw new FlowableException("condition expression returns non-Boolean: " + result + " (" + result.getClass().getName() + ")");
        }
        return (Boolean) result;
    }

}

View on GitHub (pinned to d6d39ce1c6)