flowable/flowable-engine · error · FlowableIllegalArgumentException
involvedGroups are null
Error message
involvedGroups are null
What it means
CaseInstanceQueryImpl.involvedGroups(Set<String>) throws FlowableIllegalArgumentException with message 'involvedGroups are null' when the group id set is null. Flowable requires an actual set to filter on; a null set cannot be distinguished from 'no filter' by the engine.
Solutions
- Pass an empty Set (Collections.emptySet()) instead of null when no group filter is intended, or skip the call entirely when null.
- Null-guard before the call: only apply involvedGroups when the set is non-null.
- Fix the producer (identity/tenant lookup) to return an empty collection rather than null.
- Add a DTO-level default so the groups field is always initialized to an empty set.
Example fix
// before
query.involvedGroups(filter.getGroupIds());
// after
if (filter.getGroupIds() != null && !filter.getGroupIds().isEmpty()) {
query.involvedGroups(filter.getGroupIds());
} Defensive patterns
Strategy: validation
Validate before calling
if (groupIds == null) {
throw new IllegalArgumentException("groupIds must not be null; use an empty check to skip the filter");
}
query.involvedGroups(groupIds); Type guard
boolean isApplicableGroupFilter(Set<String> groupIds) {
return groupIds != null && !groupIds.isEmpty();
} Try / catch
try {
query.involvedGroups(groupIds);
} catch (FlowableIllegalArgumentException e) {
log.warn("involvedGroups filter invalid: {}", e.getMessage());
// fall back to query without group filter
} Prevention
- Apply set-valued filters only when the set is non-null and non-empty
- Make collection fields in filter DTOs default to empty collections
- Ensure group lookups return empty collections instead of null
When it happens
Trigger: Calling caseInstanceQuery().involvedGroups(null), e.g. when a group list field in a filter DTO was never initialized or a service returned null instead of an empty collection.
Common situations: Search services aggregating the user's groups from an identity provider that returned null on failure; deserialized request bodies missing the groups field.
Related errors
- after time is null
- decision tenantId is null
- groupId is null
- identityLinkType is null
- involvedUser is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/22a9e7612cdfff7d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java:857
public CaseInstanceQuery involvedGroup(String groupId, String identityLinkType) {
if (groupId == null) {
throw new FlowableIllegalArgumentException("groupId is null");
}
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 CaseInstanceQuery involvedGroups(Set<String> groupIds) {
if (groupIds == null) {
throw new FlowableIllegalArgumentException("involvedGroups are null");
}
if (groupIds.isEmpty()) {
throw new FlowableIllegalArgumentException("involvedGroups are empty");
}
if (inOrStatement) {
this.currentOrQueryObject.involvedGroups = groupIds;
} else {
this.involvedGroups = groupIds;
}
return this;
}
@Override
public CaseInstanceQuery or() {
if (inOrStatement) {
throw new FlowableException("the query is already in an or statement");
}
View on GitHub (pinned to d6d39ce1c6)