flowable/flowable-engine · error · FlowableIllegalArgumentException
involvedGroups is null
Error message
involvedGroups is null
What it means
HistoricPlanItemInstanceQuery.involvedGroups() requires a non-null collection of group ids. Flowable throws FlowableIllegalArgumentException when null is passed; an empty collection is accepted but null is rejected because it is indistinguishable from the filter not being set. The collection is applied to the main query or the current OR-query object.
Solutions
- Pass a non-null collection (an empty List/Collection is fine if there are no groups).
- Coalesce null group lookups to an empty list before calling: Collections.emptyList().
- Only invoke involvedGroups when the collection is non-null; otherwise skip the filter.
- Fix the identity/group service so it returns an empty collection instead of null for users with no groups.
Example fix
// before query.involvedGroups(identityService.getGroupsForUser(userId)); // after List<String> groups = identityService.getGroupsForUser(userId); query.involvedGroups(groups != null ? groups : Collections.emptyList());
Defensive patterns
Strategy: validation
Validate before calling
if (involvedGroups == null) {
involvedGroups = Collections.emptyList();
}
if (!involvedGroups.isEmpty()) {
query.involvedGroups(involvedGroups);
} Type guard
boolean hasGroups(Collection<String> groups) {
return groups != null && !groups.isEmpty();
} Try / catch
try {
query.involvedGroups(involvedGroups);
} catch (FlowableIllegalArgumentException e) {
log.warn("Invalid involvedGroups filter: {}", e.getMessage());
// default to no group filter or return a validation error
} Prevention
- Coalesce group lookups to Collections.emptyList() — null collections, not empty ones, trigger this error.
- Ensure identity/group services return empty collections instead of null.
- Use Optional<List<String>> in service APIs to make 'no groups' explicit.
- Apply group filters only when the collection is non-empty.
When it happens
Trigger: Calling historicPlanItemInstanceQuery.involvedGroups(null), typically involvedGroups(userService.getGroupsForUser(userId)) where the user has no groups and the service returns null instead of an empty list, or a JSON field being absent.
Common situations: Group-based access filtering where identity/group lookup APIs return null for users without memberships; configuration objects with unset group lists; REST payloads omitting the groups array.
Related errors
- involvedUser is null
- activatedBefore is null
- assignee is null
- availableAfter is null
- availableBefore is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c30731bcdf367d90.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricPlanItemInstanceQueryImpl.java:372
}
@Override
public HistoricPlanItemInstanceQuery involvedUser(String involvedUser) {
if (involvedUser == null) {
throw new FlowableIllegalArgumentException("involvedUser is null");
}
if (inOrStatement) {
this.currentOrQueryObject.involvedUser = involvedUser;
} else {
this.involvedUser = involvedUser;
}
return this;
}
@Override
public HistoricPlanItemInstanceQuery involvedGroups(Collection<String> involvedGroups) {
if (involvedGroups == null) {
throw new FlowableIllegalArgumentException("involvedGroups is null");
}
if (inOrStatement) {
this.currentOrQueryObject.involvedGroups = involvedGroups;
} else {
this.involvedGroups = involvedGroups;
}
return this;
}
@Override
public HistoricPlanItemInstanceQuery onlyStages() {
if (inOrStatement) {
this.currentOrQueryObject.onlyStages = true;
} else {
this.onlyStages = true;
}
return this;
}View on GitHub (pinned to d6d39ce1c6)