flowable/flowable-engine · error · FlowableIllegalArgumentException

groupId is null

Error message

groupId is null

What it means

HistoricProcessInstanceQuery.involvedGroup(String groupId, String identityLinkType) requires a non-null groupId. Flowable throws FlowableIllegalArgumentException when groupId is null, as an identity-link group filter without a group id is undefined. Validation is fail-fast at query-build time.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java:622

    public HistoricProcessInstanceQuery involvedUser(String userId, String identityLinkType) {
        if (userId == null) {
            throw new FlowableIllegalArgumentException("userId is null");
        }
        if (identityLinkType == null) {
            throw new FlowableIllegalArgumentException("identityLinkType is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedUserIdentityLink = new IdentityLinkQueryObject(userId, null, identityLinkType);
        } else {
            this.involvedUserIdentityLink = new IdentityLinkQueryObject(userId, null, identityLinkType);
        }
        return this;
    }
    
    @Override
    public HistoricProcessInstanceQuery involvedGroup(String groupId, String identityLinkType) {
        if (groupId == null) {
            throw new FlowableIllegalArgumentException("groupId is null");
        }
        if (identityLinkType == null) {
            throw new FlowableIllegalArgumentException("identityLinkType is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedGroupIdentityLink = new IdentityLinkQueryObject(null, groupId, identityLinkType);
        } else {
            this.involvedGroupIdentityLink = new IdentityLinkQueryObject(null, groupId, identityLinkType);
        }
        return this;
    }

    @Override
    public HistoricProcessInstanceQuery involvedGroups(Set<String> involvedGroups) {
        if (involvedGroups == null) {
            throw new FlowableIllegalArgumentException("involvedGroups are null");
        }
        if (involvedGroups.isEmpty()) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a non-null groupId string to involvedGroup
  2. Null-check the group id first and skip the criterion or use an alternate query when absent
  3. Resolve the group from the authenticated user's memberships before building the query
  4. Use involvedGroups(Set) instead if multiple candidate groups exist

Example fix

// before
query.involvedGroup(groupId, IdentityLinkType.PARTICIPANT); // throws when groupId == null
// after
if (groupId != null) {
    query.involvedGroup(groupId, IdentityLinkType.PARTICIPANT);
}
Defensive patterns

Strategy: validation

Validate before calling

if (groupId == null) {
    throw new IllegalArgumentException("groupId is required for involvedGroup filter");
}
query.involvedGroup(groupId, IdentityLinkType.PARTICIPANT);

Type guard

boolean isValidGroupId(String groupId) {
    return groupId != null && !groupId.trim().isEmpty();
}

Try / catch

try {
    query.involvedGroup(groupId, identityLinkType);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().equals("groupId is null")) {
        // fall back to a query without the involvedGroup criterion
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling involvedGroup(null, identityLinkType) — e.g. group id resolved from user membership lookup that returned null, or a nullable request parameter.

Common situations: Multi-tenant/authorization filtering where the caller's group is unknown; group synchronization jobs that haven't run; forwarding optional group parameters from controllers.

Related errors


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