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
- Ensure at least one group id is present before calling involvedGroups
- Guard with !groups.isEmpty() and skip the criterion or return an empty result early
- Model 'no groups' explicitly: choose between an unfiltered query and a guaranteed-empty result
- 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
- Short-circuit to an empty result when the group set is empty
- Check both null and isEmpty before IN-style criteria
- Add tests for users without group memberships
- Avoid draining/filtering group collections to empty before query construction
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
- Candidate group list is empty
- groupId is null
- groupIds are empty
- identityLinkType is null
- Involved groups are empty
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)