flowable/flowable-engine · error · IllegalArgumentException

no decision table present in decision

Error message

no decision table present in decision

What it means

Flowable's DMN rule engine refuses to execute a Decision whose expression is either null or not a DecisionTable instance. RuleEngineExecutorImpl.execute() only supports decision-table decisions; a Decision backed by any other expression type (or an empty/incorrectly deployed decision) fails this instanceof guard at RuleEngineExecutorImpl.java:81-83. Because it is an IllegalArgumentException thrown before the try block, it propagates straight to the caller instead of being recorded in the audit container.

Source

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

        this.objectMapper = objectMapper;
        this.dmnEngineConfiguration = dmnEngineConfiguration;
    }

    /**
     * Executes the given decision and creates the outcome results
     *
     * @param decision            the DMN decision
     * @param executeDecisionInfo
     * @return updated execution variables map
     */
    @Override
    public DecisionExecutionAuditContainer execute(Decision decision, ExecuteDecisionContext executeDecisionInfo) {
        if (decision == null) {
            throw new IllegalArgumentException("no decision provided");
        }

        if (decision.getExpression() == null || !(decision.getExpression() instanceof DecisionTable currentDecisionTable)) {
            throw new IllegalArgumentException("no decision table present in decision");
        }

        // create execution context and audit trail
        ELExecutionContext executionContext = ELExecutionContextBuilder.build(decision, executeDecisionInfo);

        try {
            sanityCheckDecisionTable(currentDecisionTable);

            // 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

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the deployed DMN resource actually contains a <decisionTable> inside the decision (open the .dmn XML and check), then redeploy it.
  2. Check that the decision you pass to execute comes from DmnRepositoryService via createDecisionQuery / deployment, not a manually constructed Decision with no expression set.
  3. If you need non-tabular decisions, do not call this executor; use the appropriate API or add a decision table to the model.
  4. Inspect ELExecutionContextBuilder/decision conversion for your Flowable version — older DMN models may need re-export from the DMN modeler.

Example fix

// before
Decision decision = new Decision();
auditContainer = ruleEngineExecutor.execute(decision, ctx); // throws: no expression
// after
Decision decision = new Decision();
DecisionTable table = new DecisionTable();
table.setRules(rules);
decision.setExpression(table);
auditContainer = ruleEngineExecutor.execute(decision, ctx);
Defensive patterns

Strategy: validation

Validate before calling

if (decision == null || !(decision.getExpression() instanceof DecisionTable)) {
    throw new IllegalStateException("decision is not backed by a decision table; check the deployed .dmn resource");
}

Type guard

boolean isDecisionTableDecision(Decision d) {
    return d != null && d.getExpression() instanceof DecisionTable;
}

Prevention

When it happens

Trigger: Calling DmnEngine.executeDecision / RuleEngineExecutor.execute(decision, executeDecisionInfo) where decision.getExpression() returns null, or returns a non-DecisionTable expression (e.g. the decision in the deployed DMN XML is a decision defined without a decision table, or the Decision model was assembled programmatically without setting a DecisionTable expression).

Common situations: Deploying a DMN XML file whose <decision> element has no <decisionTable> child (e.g. only a literal expression), loading a Decision from a partially converted/parsed model, passing a hand-built Decision object to the executor in tests, or fetching a decision from the repository whose definition failed to convert to a decision table on an older Flowable version.

Related errors


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