flowable/flowable-engine · error · FlowableIllegalArgumentException

involvedGroups is null

Error message

involvedGroups is null

What it means

HistoricPlanItemInstanceQuery.involvedGroups() requires a non-null collection of group ids. Flowable throws FlowableIllegalArgumentException when null is passed; an empty collection is accepted but null is rejected because it is indistinguishable from the filter not being set. The collection is applied to the main query or the current OR-query object.

Solutions

  1. Pass a non-null collection (an empty List/Collection is fine if there are no groups).
  2. Coalesce null group lookups to an empty list before calling: Collections.emptyList().
  3. Only invoke involvedGroups when the collection is non-null; otherwise skip the filter.
  4. Fix the identity/group service so it returns an empty collection instead of null for users with no groups.

Example fix

// before
query.involvedGroups(identityService.getGroupsForUser(userId));

// after
List<String> groups = identityService.getGroupsForUser(userId);
query.involvedGroups(groups != null ? groups : Collections.emptyList());
Defensive patterns

Strategy: validation

Validate before calling

if (involvedGroups == null) {
    involvedGroups = Collections.emptyList();
}
if (!involvedGroups.isEmpty()) {
    query.involvedGroups(involvedGroups);
}

Type guard

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

Try / catch

try {
    query.involvedGroups(involvedGroups);
} catch (FlowableIllegalArgumentException e) {
    log.warn("Invalid involvedGroups filter: {}", e.getMessage());
    // default to no group filter or return a validation error
}

Prevention

When it happens

Trigger: Calling historicPlanItemInstanceQuery.involvedGroups(null), typically involvedGroups(userService.getGroupsForUser(userId)) where the user has no groups and the service returns null instead of an empty list, or a JSON field being absent.

Common situations: Group-based access filtering where identity/group lookup APIs return null for users without memberships; configuration objects with unset group lists; REST payloads omitting the groups array.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricPlanItemInstanceQueryImpl.java:372

    }
    
    @Override
    public HistoricPlanItemInstanceQuery involvedUser(String involvedUser) {
        if (involvedUser == null) {
            throw new FlowableIllegalArgumentException("involvedUser is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedUser = involvedUser;
        } else {
            this.involvedUser = involvedUser;
        }
        return this;
    }
    
    @Override
    public HistoricPlanItemInstanceQuery involvedGroups(Collection<String> involvedGroups) {
        if (involvedGroups == null) {
            throw new FlowableIllegalArgumentException("involvedGroups is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedGroups = involvedGroups;
        } else {
            this.involvedGroups = involvedGroups;
        }
        return this;
    }
    
    @Override
    public HistoricPlanItemInstanceQuery onlyStages() {
        if (inOrStatement) {
            this.currentOrQueryObject.onlyStages = true;
        } else {
            this.onlyStages = true;
        }
        return this;
    }

View on GitHub (pinned to d6d39ce1c6)