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

  1. Add at least one rule row to the decision table in your .dmn XML / DMN modeler and redeploy the decision.
  2. 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.
  3. Check your deployment pipeline / template for conditions that could drop rule rows.
  4. 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

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


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