flowable/flowable-engine · error · FlowableIllegalArgumentException

Involved groups are null

Error message

Involved groups are null

What it means

taskInvolvedGroups(Collection<String>) throws FlowableIllegalArgumentException when the involvedGroups collection is null. Flowable requires a concrete collection of group ids for this filter and rejects null immediately. A null list would otherwise produce invalid SQL for the identity-link join.

Solutions

  1. Pass a non-null, non-empty collection of group ids; default to Collections.emptyList() and skip the call when empty.
  2. Null-check provider results before forwarding them to the query.
  3. If group filtering is optional, only call taskInvolvedGroups() when a list is actually available.

Example fix

// before
query.taskInvolvedGroups(getUserGroups(userId));

// after
List<String> groups = getUserGroups(userId);
if (groups != null && !groups.isEmpty()) {
    query.taskInvolvedGroups(groups);
}
Defensive patterns

Strategy: validation

Validate before calling

if (involvedGroups != null && !involvedGroups.isEmpty()) {
    historicTaskInstanceQuery.taskInvolvedGroups(involvedGroups);
}

Type guard

boolean isNonEmptyGroups(Collection<String> groups) {
    return groups != null && !groups.isEmpty();
}

Try / catch

try {
    query.taskInvolvedGroups(groups);
} catch (FlowableIllegalArgumentException e) {
    log.warn("Invalid involvedGroups filter: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling taskInvolvedGroups(null) — e.g. a group-membership provider returning null, an uninitialized field, or a missing payload field passed through.

Common situations: Group lookup services that signal 'no groups' as null instead of an empty list; queries built from optional configuration that was not set.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/a36e64bb94e3fb5a. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java:1958

    @Override
    public HistoricTaskInstanceQuery taskInvolvedUser(String involvedUser) {
        if (involvedUser == null) {
            throw new FlowableIllegalArgumentException("involved user is null");
        }

        if (inOrStatement) {
            this.currentOrQueryObject.involvedUser = involvedUser;
        } else {
            this.involvedUser = involvedUser;
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery 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 (inOrStatement) {
            this.currentOrQueryObject.involvedGroups = involvedGroups;
        } else {
            this.involvedGroups = involvedGroups;
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery ignoreAssigneeValue() {
        if (inOrStatement) {
            this.currentOrQueryObject.ignoreAssigneeValue = true;
        } else {
            this.ignoreAssigneeValue = true;

View on GitHub (pinned to d6d39ce1c6)