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

  1. Verify the decisionKey matches a <decision> or <decisionService> element in the deployed DMN XML
  2. Re-deploy the DMN resource and confirm the deployment contains the expected model
  3. 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

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


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 = decisionServiceExecutionAuditContainer

View on GitHub (pinned to d6d39ce1c6)