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 trailView on GitHub (pinned to d6d39ce1c6)
Solutions
- Verify the deployed DMN resource actually contains a <decisionTable> inside the decision (open the .dmn XML and check), then redeploy it.
- Check that the decision you pass to execute comes from DmnRepositoryService via createDecisionQuery / deployment, not a manually constructed Decision with no expression set.
- If you need non-tabular decisions, do not call this executor; use the appropriate API or add a decision table to the model.
- 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
- Always deploy decisions via DmnRepositoryService and fetch them by query rather than constructing Decision objects by hand.
- Open the deployed .dmn XML and confirm the <decision> contains a <decisionTable> element.
- Pin and test your DMN modeler export pipeline; re-export models after Flowable upgrades.
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
- version must be positive
- more than one result in decision:
- more than one result
- no rules present in table
- HitPolicy %s violated.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7eaa935d06c2eb1c.
Report an issue: GitHub.