flowable/flowable-engine · error · FlowableIllegalArgumentException
Involved groups are empty
Error message
Involved groups are empty
What it means
ProcessInstanceQueryImpl.involvedGroups(Set<String>) requires a non-null, non-empty set of group IDs. Flowable throws FlowableIllegalArgumentException when an empty set is passed because an 'involved groups' filter matches nothing by definition, and an empty filter would silently produce an unusable or misleading query. The library fails fast instead of building a query with no filtering semantics.
Solutions
- Only call involvedGroups when the set has at least one element; skip the filter otherwise
- Pre-populate the set with the intended group IDs before building the query
- Fix upstream group/role resolution so it returns the actual group IDs rather than an empty collection
- Catch FlowableIllegalArgumentException and fall back to an unfiltered query if that is the desired behavior
Example fix
// before
query.involvedGroups(groupIds);
// after
if (groupIds != null && !groupIds.isEmpty()) {
query.involvedGroups(groupIds);
} else {
query = runtimeService.createProcessInstanceQuery(); // drop the filter
} Defensive patterns
Strategy: validation
Validate before calling
if (groupIds == null || groupIds.isEmpty()) {
throw new IllegalArgumentException("involvedGroups must contain at least one group id");
} Type guard
boolean hasGroups = groupIds != null && !groupIds.isEmpty();
Try / catch
try {
query.involvedGroups(groupIds);
} catch (FlowableIllegalArgumentException e) {
query = runtimeService.createProcessInstanceQuery(); // proceed unfiltered or rethrow
} Prevention
- Check isEmpty() before applying any Set-based Flowable query filter
- Skip filters entirely when no criteria were selected in the UI
- Unit-test query builders with empty collections
When it happens
Trigger: Calling processInstanceQuery.involvedGroups(new HashSet<>()) or involvedGroups(Collections.emptySet()), or passing a set built from an empty filter/selection UI. Passing null throws a sibling message 'Involved groups are null'.
Common situations: Building admin UIs where the user selected no groups but the code still applies the filter; building the set dynamically from role/tenant lookups that returned nothing; migrating code from another engine API that tolerated empty collections.
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
- callbackIds is null or empty
- executionIds is null or empty
- parentScopeIds is null or empty
- rootScopeIds is null or empty
- Task id list is empty
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ed0fc6712a0da3c5.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessInstanceQueryImpl.java:622
}
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 ProcessInstanceQuery involvedGroups(Set<String> involvedGroups) {
if (involvedGroups == null) {
throw new FlowableIllegalArgumentException("Involved groups are null");
}
if (involvedGroups.isEmpty()) {
throw new FlowableIllegalArgumentException("Involved groups are empty");
}
if (inOrStatement) {
this.currentOrQueryObject.involvedGroups = involvedGroups;
} else {
this.involvedGroups = involvedGroups;
}
return this;
}
@Override
public ProcessInstanceQuery active() {
if (inOrStatement) {
this.currentOrQueryObject.suspensionState = SuspensionState.ACTIVE;
} else {
this.suspensionState = SuspensionState.ACTIVE;
}
return this;View on GitHub (pinned to d6d39ce1c6)