flowable/flowable-engine · error · FlowableException

more than one result in decision:

Error message

more than one result in decision: 

What it means

DmnDecisionServiceImpl.executeWithSingleResult executes a DMN decision and expects the decision result to produce at most one output row per result entry. When the decision result map contains an entry with more than one row, it throws FlowableException("more than one result in decision: <decisionKey>"), because a 'single result' API cannot unambiguously return multiple rows.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/DmnDecisionServiceImpl.java:95

        return decisionResult;
    }

    @Override
    public Map<String, Object> executeWithSingleResult(ExecuteDecisionBuilder builder) {
        ExecuteDecisionContext executeDecisionContext = builder.buildExecuteDecisionContext();

        commandExecutor.execute(new EvaluateDecisionCmd(executeDecisionContext));

        Map<String, Object> singleDecisionResult = null;
        Map<String, List<Map<String, Object>>> decisionResult = composeEvaluateDecisionResult(executeDecisionContext);

        finalizeDecisionExecutionAudit(executeDecisionContext);

        for (Map.Entry<String, List<Map<String, Object>>> entry : decisionResult.entrySet()) {
            List<Map<String, Object>> decisionResults = entry.getValue();
            if (decisionResults != null && !decisionResults.isEmpty()) {
                if (decisionResults.size() > 1) {
                    throw new FlowableException("more than one result in decision: " + entry.getKey());
                }
                if (singleDecisionResult == null) {
                    singleDecisionResult = new HashMap<>();
                }
                singleDecisionResult.putAll(decisionResults.get(0));
            }
        }

        return singleDecisionResult;
    }

    @Override
    public Map<String, Object> executeDecisionWithSingleResult(ExecuteDecisionBuilder builder) {
        ExecuteDecisionContext executeDecisionContext = builder.buildExecuteDecisionContext();

        commandExecutor.execute(new ExecuteDecisionCmd(executeDecisionContext));

        Map<String, Object> singleDecisionResult = null;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Make the decision table deterministic: narrow rule conditions so at most one rule can match, or set an appropriate hit policy (e.g. FIRST/unique).
  2. Switch the caller to a multi-result API (executeDecision / collect results) if multiple outputs are legitimate.
  3. Check which decision key the exception names and inspect its overlapping rules; add a distinguishing input condition.
  4. Deduplicate or merge output columns in the model if rows are duplicates of each other.

Example fix

// before
Map<String, Object> result = ruleService.executeWithSingleResult(config);
// after
List<Map<String, Object>> results = ruleService.execute(config); // multi-result API
if (results.size() > 1) {
    logger.warn("decision matched {} rules; using first", results.size());
}
Map<String, Object> result = results.get(0);
Defensive patterns

Strategy: try-catch

Validate before calling

// Prefer the multi-result API when the decision table may match several rules:
List<Map<String, Object>> results = ruleService.execute(config);
if (results != null && results.size() > 1) {
    logger.warn("decision matched {} rules; using first", results.size());
}

Try / catch

try {
    result = ruleService.executeWithSingleResult(config);
} catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("more than one result in decision")) {
        String decisionKey = e.getMessage().substring(e.getMessage().lastIndexOf(':') + 1).trim();
        // fall back to multi-result execution for this decision
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling executeWithSingleResult against a decision table whose rules match multiple times (overlapping rules, or hit policies like COLLECT/multi-hit that legitimately return several rows) while expecting exactly one output row.

Common situations: DMN tables where several rules overlap (e.g. overlapping input ranges) so more than one rule fires; missing exclusive/FIRST hit policy; business rules changed so that what was previously unique now matches twice; using a single-result API with a COLLECT decision table.

Related errors


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