flowable/flowable-engine · error · FlowableIllegalArgumentException
Candidate group list is empty
Error message
Candidate group list is empty
What it means
taskCandidateGroupIn(Collection<String>) throws this error when the collection argument is non-null but has no elements. An empty IN-list would generate invalid or meaningless SQL, so Flowable rejects it eagerly.
Solutions
- Guard with !candidateGroups.isEmpty() before calling and skip the filter when empty.
- If 'no groups' should match nothing, return an empty result yourself without executing the query.
- If 'no groups' should match everything, build the query without any candidate-group criterion.
Example fix
// before
query.taskCandidateGroupIn(myGroups); // throws when myGroups is empty
// after
if (myGroups != null && !myGroups.isEmpty()) {
query.taskCandidateGroupIn(myGroups);
} Defensive patterns
Strategy: validation
Validate before calling
if (candidateGroups != null && !candidateGroups.isEmpty()) {
historicTaskInstanceQuery.taskCandidateGroupIn(candidateGroups);
} else {
// decide: either return an empty result or build the query without this filter
} Type guard
boolean hasGroups(Collection<String> groups) {
return groups != null && !groups.isEmpty();
} Try / catch
try {
query.taskCandidateGroupIn(candidateGroups);
} catch (FlowableIllegalArgumentException e) {
// empty list: decide semantics — short-circuit to empty result or drop the filter
return Collections.emptyList();
} Prevention
- Check isEmpty() before any taskCandidateGroupIn() call.
- Decide explicitly what 'user has no groups' means (no results vs unfiltered).
- Filter lists before querying and skip the criterion if filtering emptied them.
When it happens
Trigger: Calling taskCandidateGroupIn(new ArrayList<>()) or taskCandidateGroupIn(Collections.emptyList()) — typically after filtering a group list down to zero elements, or when the user belongs to no groups.
Common situations: Filtering groups by permission/type and passing the (possibly empty) result; users with no group memberships; split of a blank comma-separated group string yielding an empty list.
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
- Involved groups are empty
- Candidate group is null
- Candidate group list is empty
- Candidate group list is null
- Candidate user is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/df3a7c21d223dee2.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java:1926
throw new FlowableIllegalArgumentException("Invalid query usage: cannot set both candidateGroup and candidateGroupIn");
}
if (inOrStatement) {
this.currentOrQueryObject.candidateGroup = candidateGroup;
} else {
this.candidateGroup = candidateGroup;
}
return this;
}
@Override
public HistoricTaskInstanceQuery taskCandidateGroupIn(Collection<String> candidateGroups) {
if (candidateGroups == null) {
throw new FlowableIllegalArgumentException("Candidate group list is null");
}
if (candidateGroups.isEmpty()) {
throw new FlowableIllegalArgumentException("Candidate group list is empty");
}
if (candidateGroup != null) {
throw new FlowableIllegalArgumentException("Invalid query usage: cannot set both candidateGroupIn and candidateGroup");
}
if (inOrStatement) {
this.currentOrQueryObject.candidateGroups = candidateGroups;
} else {
this.candidateGroups = candidateGroups;
}
return this;
}
@Override
public HistoricTaskInstanceQuery taskInvolvedUser(String involvedUser) {
if (involvedUser == null) {
throw new FlowableIllegalArgumentException("involved user is null");View on GitHub (pinned to d6d39ce1c6)