flowable/flowable-engine · error · FlowableException

more than one result

Error message

more than one result

What it means

DmnDecisionServiceImpl.executeDecisionWithSingleResult runs a DMN decision and converts its result list into a single row. If the composed decision result contains more than one row it throws FlowableException("more than one result"), since a single-result API has no way to represent multiple matching output rows.

Solutions

  1. Adjust the decision model so exactly one row is produced per execution (exclusive conditions or FIRST hit policy).
  2. Use the multi-result execution API instead and pick/aggregate the row you need.
  3. Aggregate in the decision itself (e.g. return a sum or combined output) so the result is a single row.
  4. Inspect input values with a test deployment to identify which rules overlap for the failing payload.

Example fix

// before
Map<String, Object> result = dmnService.executeDecisionWithSingleResult(ctx);
// after
List<Map<String, Object>> results = dmnService.executeDecision(ctx);
if (results == null || results.isEmpty()) {
    throw new IllegalStateException("decision returned no result");
}
Map<String, Object> result = results.get(0);
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the decision cannot yield multiple rows, or use the multi-result API:
List<Map<String, Object>> results = dmnService.executeDecision(ctx);
if (results != null && results.size() > 1) {
    throw new IllegalStateException("expected single decision result, got " + results.size());
}

Try / catch

try {
    result = dmnService.executeDecisionWithSingleResult(ctx);
} catch (FlowableException e) {
    if ("more than one result".equals(e.getMessage())) {
        // retry with the multi-result API and aggregate/pick a row
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling executeDecisionWithSingleResult for a decision expression/table that evaluates to multiple results — e.g. a decision table with overlapping rules producing several rows, or a collection-style decision returning multiple items — when the caller expected exactly one.

Common situations: Overlapping rule conditions in the DMN table (input ranges like x<10 and x>5); using COLLECT/multi-hit policies with a single-result invocation; business data changes causing previously-unique rules to both fire; forgotten aggregation (sum/count) upstream of the single-result call.

Related errors


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

Appendix: source

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

        }

        return singleDecisionResult;
    }

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

        commandExecutor.execute(new ExecuteDecisionCmd(executeDecisionContext));

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

        finalizeDecisionExecutionAudit(executeDecisionContext);

        if (decisionResult != null && !decisionResult.isEmpty()) {
            if (decisionResult.size() > 1) {
                throw new FlowableException("more than one result");
            }
            singleDecisionResult = decisionResult.get(0);
        }

        return singleDecisionResult;
    }

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

        commandExecutor.execute(new ExecuteDecisionServiceCmd(executeDecisionContext));

        Map<String, Object> singleDecisionResult = new HashMap<>();
        Map<String, List<Map<String, Object>>> decisionResult = composeDecisionServiceResult(executeDecisionContext);

        finalizeDecisionExecutionAudit(executeDecisionContext);

View on GitHub (pinned to d6d39ce1c6)