flowable/flowable-engine · error · FlowableException

Query return " + results.size() + " results instead of max 1

Error message

Query return " + results.size() + " results instead of max 1

What it means

Result-shape guard in AbstractQuery.executeSingleResult: singleResult() was called but the query matched more than one entity (count in message); the query's filters are too broad for a single-result expectation.

Solutions

  1. Tighten the query filters (id, key) so exactly one row matches
  2. Use list() when multiple results are legitimate

Example fix

// before
Execution e = runtimeService.createExecutionQuery()
    .processInstanceId(pid).singleResult();
// after
Execution e = runtimeService.createExecutionQuery()
    .processInstanceId(pid).processDefinitionKey(key).singleResult();
Defensive patterns

Strategy: validation

Validate before calling

long matches = runtimeService.createExecutionQuery()
    .processInstanceId(pid).count();
if (matches > 1) {
    throw new IllegalStateException("criteria not unique: " + matches);
}

Try / catch

try {
    return query.singleResult();
} catch (FlowableException e) {
    if (e.getMessage().contains("instead of max 1")) {
        return query.list().get(0);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling e.g. taskQuery().processInstanceId(pid).singleResult() when several tasks/executions/variables match the filter — i.e. the query criteria are not unique.

Common situations: Assuming processInstanceId returns exactly one execution when there are concurrent child executions; filters that match historical duplicates; missing unique constraint in custom data.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/query/AbstractQuery.java:191

            return executeList(commandContext);
        } else {
            return executeCount(commandContext);
        }
    }

    public abstract long executeCount(CommandContext commandContext);

    /**
     * Executes the actual query to retrieve the list of results.
     */
    public abstract List<U> executeList(CommandContext commandContext);

    public U executeSingleResult(CommandContext commandContext) {
        List<U> results = executeList(commandContext);
        if (results.size() == 1) {
            return results.get(0);
        } else if (results.size() > 1) {
            throw new FlowableException("Query return " + results.size() + " results instead of max 1");
        }
        return null;
    }

}

View on GitHub (pinned to d6d39ce1c6)