flowable/flowable-engine · error · IllegalArgumentException
no rules present in table
Error message
no rules present in table
What it means
The DMN rule engine requires at least one rule in the decision table being evaluated. evaluateDecisionTable throws this IllegalArgumentException when the DecisionTable is null or its getRules() list is empty (RuleEngineExecutorImpl.java:108-110). Since it is thrown inside execute's try block but is an IllegalArgumentException (not FlowableException), it is not captured into the audit container and propagates to the caller.
Source
Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/RuleEngineExecutorImpl.java:109
// evaluate decision table
evaluateDecisionTable(currentDecisionTable, executionContext);
} catch (FlowableException fe) {
LOGGER.error("decision table execution sanity check failed", fe);
executionContext.getAuditContainer().setFailedWithException(fe);
executionContext.getAuditContainer().setExceptionMessage(getExceptionMessage(fe));
} finally {
// end audit trail
executionContext.getAuditContainer().stopAudit(dmnEngineConfiguration.getClock().getCurrentTime());
}
return executionContext.getAuditContainer();
}
protected void evaluateDecisionTable(DecisionTable decisionTable, ELExecutionContext executionContext) {
if (decisionTable == null || decisionTable.getRules().isEmpty()) {
throw new IllegalArgumentException("no rules present in table");
}
LOGGER.debug("Start table evaluation: {}", decisionTable.getId());
if (executionContext == null) {
throw new FlowableException("no execution context available");
}
try {
// evaluate rule conditions
Map<Integer, List<RuleOutputClauseContainer>> validRuleOutputEntries = new HashMap<>();
for (DecisionRule rule : decisionTable.getRules()) {
boolean ruleResult = executeRule(rule, executionContext);
if (ruleResult) {
// evaluate decision table hit policy validity
if (getHitPolicyBehavior(decisionTable.getHitPolicy()) instanceof EvaluateRuleValidityBehavior) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add at least one rule row to the decision table in your .dmn XML / DMN modeler and redeploy the decision.
- If you truly need a no-rule table, guard the call: check decisionTable.getRules().isEmpty() before executing and skip or return an empty audit result.
- Check your deployment pipeline / template for conditions that could drop rule rows.
- Re-export the model from the DMN modeler to ensure the converter populated rules.
Example fix
// before
ruleEngineExecutor.execute(decision, ctx); // table has no rules -> IllegalArgumentException
// after
DecisionTable table = (DecisionTable) decision.getExpression();
if (table != null && !table.getRules().isEmpty()) {
ruleEngineExecutor.execute(decision, ctx);
} Defensive patterns
Strategy: validation
Validate before calling
DecisionTable table = decision != null && decision.getExpression() instanceof DecisionTable
? (DecisionTable) decision.getExpression() : null;
if (table == null || table.getRules() == null || table.getRules().isEmpty()) {
throw new IllegalStateException("decision table has no rules to evaluate");
} Type guard
boolean hasRules(Decision d) {
return d != null && d.getExpression() instanceof DecisionTable t && t.getRules() != null && !t.getRules().isEmpty();
} Prevention
- Never save a decision table without at least one rule row; enforce this in model review or CI validation of .dmn files.
- Add a unit test that executes each deployed decision and asserts rules exist.
- Check dynamic DMN generators/templates for loops that may render zero rules.
When it happens
Trigger: Executing a decision table that was deployed with zero <rule> rows, a programmatically built DecisionTable without rules, or code that filters/strips rules before calling execute. Also triggered when decisionTable is null, though execute() normally guards that earlier.
Common situations: Modeling a decision table in the DMN editor and saving it with the rule rows all removed, generating DMN XML from a template where the rules loop rendered nothing, or an incomplete conversion producing an empty rules list.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- version must be positive
- no decision table present in decision
- Set of process instance ids is empty
- Could not find an app definition with id '<appDefinitionId>
- Could not find a deployment with id '<deploymentId>
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/39aa484546071031.
Report an issue: GitHub.