flowable/flowable-engine · error · FlowableIllegalArgumentException

involvedGroups are empty

Error message

involvedGroups are empty

What it means

HistoricProcessInstanceQuery.involvedGroups(Set<String>) rejects empty sets. Flowable throws FlowableIllegalArgumentException when involvedGroups is non-null but empty, because an empty IN filter on group identity links is undefined. Validation is fail-fast at query-build time.

Solutions

  1. Ensure at least one group id is present before calling involvedGroups
  2. Guard with !groups.isEmpty() and skip the criterion or return an empty result early
  3. Model 'no groups' explicitly: choose between an unfiltered query and a guaranteed-empty result
  4. Use involvedGroup(String, String) if only a single group is relevant

Example fix

// before
query.involvedGroups(groups); // throws when groups.isEmpty()
// after
if (groups != null && !groups.isEmpty()) {
    query.involvedGroups(groups);
} else {
    return Collections.emptyList();
}
Defensive patterns

Strategy: validation

Validate before calling

if (groups == null || groups.isEmpty()) {
    return Collections.emptyList(); // nothing to query
}
query.involvedGroups(groups);

Type guard

boolean hasGroups(Set<String> groups) {
    return groups != null && !groups.isEmpty();
}

Try / catch

try {
    query.involvedGroups(groups);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("empty")) {
        return Collections.emptyList();
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling involvedGroups(groups) with a non-null but empty Set — e.g. new HashSet<>() passed directly, or the group list emptied after filtering/removals upstream.

Common situations: Users with no group memberships in authorization-filtered history queries; batch jobs that drained the group list before query construction; pagination logic yielding an empty id batch.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java:641

        }
        if (identityLinkType == null) {
            throw new FlowableIllegalArgumentException("identityLinkType is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedGroupIdentityLink = new IdentityLinkQueryObject(null, groupId, identityLinkType);
        } else {
            this.involvedGroupIdentityLink = new IdentityLinkQueryObject(null, groupId, identityLinkType);
        }
        return this;
    }

    @Override
    public HistoricProcessInstanceQuery involvedGroups(Set<String> involvedGroups) {
        if (involvedGroups == null) {
            throw new FlowableIllegalArgumentException("involvedGroups are null");
        }
        if (involvedGroups.isEmpty()) {
            throw new FlowableIllegalArgumentException("involvedGroups are empty");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedGroups = involvedGroups;
        } else {
            this.involvedGroups = involvedGroups;
        }
        return this;
    }

    @Override
    public HistoricProcessInstanceQuery includeProcessVariables() {
        this.includeProcessVariables = true;
        return this;
    }

    @Override
    public HistoricProcessInstanceQuery includeProcessVariables(Collection<String> variableNames) {
        if (variableNames == null || variableNames.isEmpty()) {

View on GitHub (pinned to d6d39ce1c6)