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

  1. Pass a non-null collection of group ids; initialize or default it (e.g. Collections.emptyList()) before the call.
  2. Skip the filter when the group list is not available.
  3. 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

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


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)