flowable/flowable-engine · error · FlowableException
condition expression returns null
Error message
condition expression returns null
What it means
When evaluating a DMN rule's input condition, Flowable calls the JUEL expression via RuleExpressionCondition.evaluate and requires a Boolean answer (does the rule match or not). If the expression evaluates to null — e.g. it references an undefined variable or compares against a missing value — Flowable cannot decide the rule and throws this exception. A null condition result is never treated as 'false'; it is a hard error.
Solutions
- Ensure every variable referenced by the decision table's input expressions is set on the execution/variable container before the DMN task runs.
- Check the input expression in the decision table for typos or references to variables not in scope (EL is case-sensitive).
- Make the expression null-safe, e.g. use `${var != null && var == 'X'}` so the condition always yields a Boolean.
- Set a default value for the variable before invoking the DMN rule task.
- Wrap the rule execution in try-catch for FlowableException and log which input expression produced the null.
Example fix
// before (DMN input expression)
${customerLevel == 'gold'} // customerLevel is null -> error
// after
${customerLevel != null && customerLevel == 'gold'} Defensive patterns
Strategy: type-guard
Validate before calling
if (!execution.hasVariable("customerLevel")) throw new IllegalStateException("DMN input variable customerLevel missing"); Type guard
boolean isBooleanResult(Object result) { return result instanceof Boolean; } Try / catch
try {
boolean hit = ruleExpression.evaluate(...);
} catch (FlowableException e) {
if ("condition expression returns null".equals(e.getMessage())) {
log.warn("DMN condition null, variable missing?", e);
}
} Prevention
- Set every variable referenced by decision-table input expressions before evaluation.
- Write null-safe EL conditions (var != null && ...).
- Use case-sensitive variable name checks against the DMN expressions.
- Give variables default values at process start.
- Keep EL functions returning Boolean only.
When it happens
Trigger: executeInputExpression calls evaluate and the JUEL expression returns null: a referenced execution variable is absent from the variable container, an EL function returns null, or the expression is a plain null-valued operand.
Common situations: Decision table input expression references a process variable that was never set; variable name typo (case-sensitive EL); a custom EL function returns Optional.empty/null; null is passed as the hit input value.
Related errors
- Could not create conclusion result
- byte array for resource
- condition expression returns non-Boolean
- Could not create execution variable
- could not create result variable
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/b63ae038e368b716.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/el/RuleExpressionCondition.java:45
*/
public class RuleExpressionCondition {
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)