flowable/flowable-engine · error · FlowableException
Execution was not a decision or decision service
Error message
Execution was not a decision or decision service
What it means
composeEvaluateDecisionResult expects the executed DMN element to be either a Decision or a DecisionService. When the ExecuteDecisionContext holds neither (e.g. no DmnElement was resolved or it is another element type), Flowable logs and throws this FlowableException.
Solutions
- Verify the decisionKey matches a <decision> or <decisionService> element in the deployed DMN XML
- Re-deploy the DMN resource and confirm the deployment contains the expected model
- Check that you are using the DMN engine's APIs for DMN artifacts, not process/case keys
Example fix
// before
dmnEngineRule.getDmnEngine().getDecisionService().executeDecision(key, vars); // key points at a non-decision element
// after
DmnRepositoryService repo = dmnEngine.getDmnRepositoryService();
if (repo.createDecisionTableQuery().decisionTableKey(key).count() > 0) { /* evaluate */ } Defensive patterns
Strategy: validation
Validate before calling
DmnDecision decision = dmnRepositoryService.getDmnModel(deploymentId).getDecisionById(decisionKey);
if (decision == null) throw new IllegalArgumentException("Key " + decisionKey + " is not a decision in deployment " + deploymentId); Try / catch
try {
Map<String,Object> res = decisionService.decisionResult(ctx);
} catch (FlowableException e) {
if (e.getMessage().contains("not a decision or decision service")) { /* re-check the key/deployment */ }
throw e;
} Prevention
- Keep decision keys in constants shared with the DMN model
- Validate keys against the deployed model before evaluating
- Re-verify keys after re-deploying changed models
When it happens
Trigger: Calling decision evaluation (decisionResult/executeWithAuditTrail paths) with a decision key that does not resolve to a Decision or DecisionService element, or a context whose DmnElement was never set.
Common situations: Typo'd or stale decision key after re-deploying a changed model; passing an artifact key from a different engine (e.g. a process or case element); programmatic misuse of internal APIs with a partially-built ExecuteDecisionContext.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Main execution was a not a decision service
- Could not find decision service with id
- decisionKey is null
- no decision service with id
- a suspended
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4610e57ac7db5f6f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/DmnDecisionServiceImpl.java:204
DecisionServiceExecutionAuditContainer decisionServiceExecutionAuditContainer = (DecisionServiceExecutionAuditContainer) finalizeDecisionExecutionAudit(executeDecisionContext);
return decisionServiceExecutionAuditContainer;
}
protected Map<String, List<Map<String, Object>>> composeEvaluateDecisionResult(ExecuteDecisionContext executeDecisionContext) {
Map<String, List<Map<String, Object>>> result;
// check if execution was Decision or DecisionService
if (executeDecisionContext.getDmnElement() instanceof DecisionService) {
result = composeDecisionServiceResult(executeDecisionContext);
} else if (executeDecisionContext.getDmnElement() instanceof Decision) {
result = new HashMap<>();
result.put(executeDecisionContext.getDecisionKey(), executeDecisionContext.getDecisionExecution().getDecisionResult());
} else {
LOGGER.error("Execution was not a decision or decision service");
throw new FlowableException("Execution was not a decision or decision service");
}
return result;
}
protected List<Map<String, Object>> composeDecisionResult(ExecuteDecisionContext executeDecisionContext) {
return executeDecisionContext.getDecisionExecution().getDecisionResult();
}
protected Map<String, List<Map<String, Object>>> composeDecisionServiceResult(ExecuteDecisionContext executeDecisionContext) {
// check if execution was Decision or DecisionService
if (executeDecisionContext.getDmnElement() instanceof DecisionService decisionService) {
Map<String, List<Map<String, Object>>> decisionServiceResult = new HashMap<>();
DecisionServiceExecutionAuditContainer decisionServiceExecutionAuditContainer = (DecisionServiceExecutionAuditContainer) executeDecisionContext.getDecisionExecution();
boolean multipleResults = decisionService.getOutputDecisions().size() > 1;
for (DmnElementReference elementReference : decisionService.getOutputDecisions()) {
DecisionExecutionAuditContainer childDecisionExecution = decisionServiceExecutionAuditContainerView on GitHub (pinned to d6d39ce1c6)