flowable/flowable-engine · error · FlowableException

<exception message from evaluation failure>

Error message

<exception message from evaluation failure>

What it means

When evaluating a rule's input condition, any non-FlowableException thrown by the EL expression evaluation is wrapped into a FlowableException whose message is the root-cause message (via getExceptionMessage, which walks to the deepest cause) and rethrown (RuleEngineExecutorImpl.java:204-208). A failed audit entry with that message is also recorded on the input entry. The actual message is dynamic — e.g. 'Unknown property used in expression', class-cast or conversion errors from the input expression — and it ultimately marks the decision execution failed in the audit container.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/RuleEngineExecutorImpl.java:207

                    conditionResult = executeInputExpressionEvaluation(conditionContainer, executionContext);
                }

                // add audit entry
                executionContext.getAuditContainer().addInputEntry(rule.getRuleNumber(), inputEntryId, conditionResult);

                LOGGER.debug("input entry {} ( {} {} ): {}", inputEntryId,
                        conditionContainer.getInputClause().getInputExpression().getText(),
                        inputEntryText, conditionResult);

            } catch (FlowableException ade) {
                // add failed audit entry and rethrow
                executionContext.getAuditContainer().addInputEntry(rule.getRuleNumber(), inputEntryId, getExceptionMessage(ade), null);
                throw ade;

            } catch (Exception e) {
                // add failed audit entry and rethrow
                executionContext.getAuditContainer().addInputEntry(rule.getRuleNumber(), inputEntryId, getExceptionMessage(e), null);
                throw new FlowableException(getExceptionMessage(e), e);
            }

            // exit evaluation loop if a condition is evaluated false
            if (!conditionResult) {
                break;
            }
        }

        if (conditionResult) {
            // mark rule valid
            executionContext.getAuditContainer().markRuleValid(rule.getRuleNumber());
        }

        // mark rule end
        executionContext.getAuditContainer().markRuleEnd(rule.getRuleNumber());

        LOGGER.debug("End rule {} evaluation", rule.getRuleNumber());
        return conditionResult;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Read the audit container's exceptionMessage / the wrapped cause to get the real root-cause message and fix the offending input expression.
  2. Ensure all variables referenced in the decision table's input expressions are provided in the ExecuteDecisionContext (variables/fallbackScopeProperties) with correct types.
  3. Validate the .dmn condition expressions (EL syntax, matching types) in the DMN modeler before deploying.
  4. Catch FlowableException from execute() and inspect DecisionExecutionAuditContainer.isFailed()/getExceptionMessage() for graceful degradation.

Example fix

// before: condition references undefined variable
// input expression text: ${amount > 100} but 'amount' not passed -> FlowableException(Unknown property...)
// after: pass the variable before executing
Map<String, Object> vars = new HashMap<>();
vars.put("amount", 250);
ExecuteDecisionContext ctx = new ExecuteDecisionContext(decisionKey, vars, null, false);
DecisionExecutionAuditContainer audit = ruleEngineExecutor.execute(decision, ctx);
if (audit.isFailed()) {
    throw new IllegalStateException(audit.getExceptionMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

for (String var : referencedVariables(decision)) {
    if (executeDecisionInfo.getVariables() == null || !executeDecisionInfo.getVariables().containsKey(var)) {
        throw new IllegalStateException("missing decision input variable: " + var);
    }
}

Try / catch

try {
    audit = ruleEngineExecutor.execute(decision, ctx);
} catch (FlowableException fe) {
    String rootCause = fe.getCause() != null ? fe.getCause().getMessage() : fe.getMessage();
    log.error("Input expression evaluation failed: {}", rootCause, fe);
    // audit container also exposes isFailed()/getExceptionMessage()
}

Prevention

When it happens

Trigger: Any runtime exception inside ELExpressionExecutor.executeInputExpression for a rule input entry: referencing a variable not present in the execution context, an EL syntax error in the condition text, a type-conversion failure (e.g. comparing a string to a number), or a NullPointerException inside a custom EL function. Called from executeRule during evaluateDecisionTable.

Common situations: Typos or missing variables in DMN table condition expressions, missing input data passed via ExecuteDecisionContext fallback variables, incompatible operand types in conditions (string vs number/date), or using functions not available in the expression manager configuration.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/68e2cf6828e4263d. Report an issue: GitHub.