flowable/flowable-engine · error · FlowableException
no execution context available
Error message
no execution context available
What it means
evaluateDecisionTable requires a non-null ELExecutionContext to evaluate expressions and record the audit trail. When the passed context is null it throws FlowableException("no execution context available") (RuleEngineExecutorImpl.java:114-116). In the default flow execute() builds the context via ELExecutionContextBuilder.build so this only fires when build returns null (e.g. a broken custom builder) or when evaluateDecisionTable is invoked directly with a null context. Unlike the IllegalArgumentException guards, this FlowableException is caught by execute() and recorded on the audit container as a failed decision.
Source
Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/RuleEngineExecutorImpl.java:115
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) {
((EvaluateRuleValidityBehavior) getHitPolicyBehavior(decisionTable.getHitPolicy())).evaluateRuleValidity(rule.getRuleNumber(), executionContext);
}
// add valid rule output(s)
validRuleOutputEntries.put(rule.getRuleNumber(), rule.getOutputEntries());
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Ensure ELExecutionContextBuilder.build returns a valid context — check your DmnEngineConfiguration and any custom builder overrides.
- In tests, construct a real ELExecutionContext (via ELExecutionContextBuilder.build(decision, executeDecisionInfo)) instead of passing/mock-returning null.
- If calling evaluateDecisionTable directly, always build the context first.
- Catch FlowableException around execute() and inspect the audit container's exceptionMessage if you want graceful failure handling.
Example fix
// before ruleEngineExecutor.evaluateDecisionTable(table, null); // FlowableException // after ELExecutionContext ctx = ELExecutionContextBuilder.build(decision, executeDecisionInfo); ruleEngineExecutor.evaluateDecisionTable(table, ctx);
Defensive patterns
Strategy: validation
Validate before calling
ELExecutionContext ctx = ELExecutionContextBuilder.build(decision, executeDecisionInfo);
if (ctx == null) {
throw new IllegalStateException("ELExecutionContextBuilder returned null; check custom builder/engine configuration");
} Try / catch
try {
audit = ruleEngineExecutor.execute(decision, executeDecisionInfo);
} catch (FlowableException fe) {
log.error("DMN execution failed: {}", fe.getMessage(), fe);
audit = null; // or fall back
} Prevention
- Do not stub ELExecutionContextBuilder.build to return null in tests; build a real context.
- Review custom DmnEngineConfiguration for overrides that could break context creation.
- Call execute() rather than the protected evaluateDecisionTable directly.
When it happens
Trigger: Subclassing RuleEngineExecutorImpl / overriding ELExecutionContextBuilder so build() yields null; calling the protected evaluateDecisionTable(table, null) directly from custom code; any path where execute()'s context construction is bypassed or stubbed in tests.
Common situations: Unit tests mocking ELExecutionContextBuilder.build to return null, custom DMN engine configuration that replaces the context builder, or reflective/internal calls into evaluateDecisionTable without a proper context.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/008858708590dc2f.
Report an issue: GitHub.