flowable/flowable-engine · error · FlowableIllegalArgumentException
Candidate group list is null
Error message
Candidate group list is null
What it means
taskCandidateGroupIn(Collection<String>) throws FlowableIllegalArgumentException when the candidateGroups collection argument is null. Flowable validates required collection arguments before assigning them to the query. This check runs before the empty-list and mutual-exclusion checks.
Solutions
- Pass a non-null collection of group ids; initialize or default it (e.g. Collections.emptyList()) before the call.
- Skip the filter when the group list is not available.
- Check GroupsProvider results for null before forwarding to the query.
Example fix
// before
query.taskCandidateGroupIn(userGroups);
// after
if (userGroups != null && !userGroups.isEmpty()) {
query.taskCandidateGroupIn(userGroups);
} Defensive patterns
Strategy: validation
Validate before calling
if (candidateGroups == null) {
throw new IllegalArgumentException("candidateGroups must not be null; pass a non-empty list or skip the filter");
}
if (!candidateGroups.isEmpty()) {
historicTaskInstanceQuery.taskCandidateGroupIn(candidateGroups);
} Type guard
boolean isNonEmptyGroups(Collection<String> groups) {
return groups != null && !groups.isEmpty();
} Try / catch
try {
query.taskCandidateGroupIn(candidateGroups);
} catch (FlowableIllegalArgumentException e) {
log.warn("Invalid candidateGroupIn filter: {}", e.getMessage());
} Prevention
- Default null group collections to an empty list at the service boundary and skip the filter.
- Null-check results from group/role providers before querying.
- Validate request DTOs so the groups field is always present.
When it happens
Trigger: Calling taskCandidateGroupIn(null) — e.g. a groups field that was never initialized, or a nullable result of a role-lookup API passed directly in.
Common situations: Group list obtained from user/role providers that can return null; deserialized request bodies missing the 'groups' field; map lookups with a missing key returning null.
Related errors
- Candidate group is null
- Candidate user is null
- Involved groups are null
- involved user is null
- Assignee is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/9a5aea5a06f69b5f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java:1922
throw new FlowableIllegalArgumentException("Candidate group is null");
}
if (candidateGroups != null) {
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;
}
View on GitHub (pinned to d6d39ce1c6)