flowable/flowable-engine · error · FlowableException

Decision has multiple results

Error message

Decision has multiple results

What it means

DmnDecisionRuleResult wraps a DMN decision's rule output rows. getSingleRuleResult() is only valid when the decision produced exactly one result; with more than one row it refuses to guess which to return and throws. Use getFirstRuleResult() or the full result list when multiple outcomes are expected.

Source

Thrown at modules/flowable-dmn-api/src/main/java/org/flowable/dmn/api/DmnDecisionRuleResult.java:56

        for (Map<String, Object> ruleOutputValues : ruleResults) {
            outputValues.add(ruleOutputValues.get(outputName));
        }
        return outputValues;
    }

    public Map<String, Object> getFirstRuleResult() {
        if (ruleResults.size() > 0) {
            return ruleResults.get(0);
        } else {
            return null;
        }
    }

    public Map<String, Object> getSingleRuleResult() {
        if (ruleResults.isEmpty()) {
            return null;
        } else if (ruleResults.size() > 1) {
            throw new FlowableException("Decision has multiple results");
        } else {
            return getFirstRuleResult();
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Call getFirstRuleResult() if any result is acceptable.
  2. Iterate the full ruleResults list and handle each row.
  3. Tighten decision table rules / set hit policy (e.g. UNIQUE or FIRST) so only one result is produced.
  4. Check ruleResults.isEmpty()/size() before calling getSingleRuleResult().

Example fix

// before
Map<String, Object> result = ruleResult.getSingleRuleResult();
// after
Map<String, Object> result = ruleResult.getFirstRuleResult();
Defensive patterns

Strategy: type-guard

Validate before calling

if (ruleResult != null && ruleResult.size() == 1) {
    Map<String, Object> single = ruleResult.getSingleRuleResult();
} else if (ruleResult != null && ruleResult.size() > 1) {
    // handle multi-result case first
}

Type guard

boolean hasSingleResult(DmnDecisionRuleResult r) { return r != null && r.size() == 1; }

Try / catch

try { return ruleResult.getSingleRuleResult(); } catch (FlowableException e) { if ("Decision has multiple results".equals(e.getMessage())) return ruleResult.getFirstRuleResult(); throw e; }

Prevention

When it happens

Trigger: Calling dmnDecisionService.executeDecision... then getSingleRuleResult() on a decision table whose rules matched multiple times (multiple output rows), or a decision whose expression produced several outputs.

Common situations: Multi-hit decision tables (hit policy not unique), rules with overlapping conditions so several rules fire, developers assuming single-result semantics.

Related errors


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