flowable/flowable-engine · error · FlowableIllegalArgumentException
Involved groups are empty
Error message
Involved groups are empty
What it means
TaskQueryImpl.taskInvolvedGroups() throws this when the passed collection is non-null but empty. An empty collection would yield an invalid IN () clause or match nothing, so Flowable rejects it explicitly. Use null/omission for 'no filter' instead of an empty list.
Solutions
- Only call taskInvolvedGroups() when the collection has at least one element.
- Handle the empty case by skipping the filter or returning an intentionally empty result.
- Fix the logic that produces an empty group list if groups are mandatory.
- If 'no groups' is valid, model it by not setting the filter rather than passing an empty list.
Example fix
// before
TaskQuery query = taskService.createTaskQuery().taskInvolvedGroups(groups);
// after
TaskQuery query = taskService.createTaskQuery();
if (groups != null && !groups.isEmpty()) {
query = query.taskInvolvedGroups(groups);
} Defensive patterns
Strategy: validation
Validate before calling
if (involvedGroups == null || involvedGroups.isEmpty()) {
throw new IllegalArgumentException("involvedGroups must contain at least one group");
}
query.taskInvolvedGroups(involvedGroups); Type guard
boolean isNonEmptyGroups(Collection<String> g) { return g != null && !g.isEmpty(); } Try / catch
try {
query.taskInvolvedGroups(groups);
} catch (FlowableIllegalArgumentException e) {
logger.warn("Empty/null involved groups: {}", e.getMessage());
return Collections.emptyList(); // or skip the filter
} Prevention
- Treat 'no filter' as omitting the setter, not passing an empty list
- Decide explicit semantics for the empty-groups case (empty result vs unfiltered)
- Validate collections after any filtering/reduction step
- Cover empty-list inputs in query-builder tests
When it happens
Trigger: Calling taskQuery.taskInvolvedGroups(new ArrayList<>()) or any collection where isEmpty() is true, often the result of filtering a group list to zero entries.
Common situations: Group list computed at runtime (e.g. user's groups) ends up empty because the user belongs to no groups; upstream filter removed all items; default-initialized empty list passed unconditionally.
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
- Process category list is empty
- Process instance id list is empty
- Task assignee list is empty
- Task category list is empty
- at least one of userId or groups must be provided
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d2d406bfc7020e17.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/TaskQueryImpl.java:609
public TaskQueryImpl taskInvolvedUser(String involvedUser) {
if (involvedUser == null) {
throw new FlowableIllegalArgumentException("Involved user is null");
}
if (orActive) {
currentOrQueryObject.involvedUser = involvedUser;
} else {
this.involvedUser = involvedUser;
}
return this;
}
@Override
public TaskQueryImpl taskInvolvedGroups(Collection<String> involvedGroups) {
if (involvedGroups == null) {
throw new FlowableIllegalArgumentException("Involved groups are null");
}
if (involvedGroups.isEmpty()) {
throw new FlowableIllegalArgumentException("Involved groups are empty");
}
if (orActive) {
currentOrQueryObject.involvedGroups = involvedGroups;
} else {
this.involvedGroups = involvedGroups;
}
return this;
}
@Override
public TaskQueryImpl taskCandidateGroup(String candidateGroup) {
if (candidateGroup == null) {
throw new FlowableIllegalArgumentException("Candidate group is null");
}
if (candidateGroups != null) {
throw new FlowableIllegalArgumentException("Invalid query usage: cannot set both candidateGroup and candidateGroupIn");
}View on GitHub (pinned to d6d39ce1c6)