flowable/flowable-engine · error · FlowableIllegalArgumentException

userId is null

Error message

userId is null

What it means

The two-argument CaseInstanceQueryImpl.involvedUser(String userId, String identityLinkType) throws FlowableIllegalArgumentException when userId is null. This variant filters case instances by a specific identity link type (e.g. participant, owner) for a user, so both parts are required to build the identity-link filter.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java:825

    }
    
    @Override
    public CaseInstanceQuery involvedUser(String userId) {
        if (userId == null) {
            throw new FlowableIllegalArgumentException("involvedUser is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.involvedUser = userId;
        } else {
            this.involvedUser = userId;
        }
        return this;
    }
    
    @Override
    public CaseInstanceQuery 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 CaseInstanceQuery involvedGroup(String groupId, String identityLinkType) {
        if (groupId == null) {
            throw new FlowableIllegalArgumentException("groupId is null");
        }
        if (identityLinkType == null) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Validate userId is non-null (and typically non-blank) before calling the two-argument involvedUser.
  2. Resolve the user id from the authenticated context first; refuse to run the query when it cannot be resolved.
  3. If the identity-link filter is optional, guard the whole call behind a null/empty check on the filter object.
  4. Fix the deserialization/binding layer that produced a null userId.

Example fix

// before
query.involvedUser(userContext.getUserId(), "participant");
// after
String userId = userContext.getUserId();
if (userId != null) {
    query.involvedUser(userId, "participant");
}
Defensive patterns

Strategy: validation

Validate before calling

if (userId == null) {
    throw new IllegalArgumentException("userId required for involvedUser(userId, identityLinkType)");
}
query.involvedUser(userId, identityLinkType);

Type guard

boolean canFilterByUser(String userId) {
    return userId != null && !userId.isBlank();
}

Try / catch

try {
    query.involvedUser(userId, identityLinkType);
} catch (FlowableIllegalArgumentException e) {
    log.error("Invalid involvedUser filter: {}", e.getMessage());
    throw new BadRequestException("userId is required", e);
}

Prevention

When it happens

Trigger: Calling involvedUser(null, "participant") or passing a null user id captured from a UI filter or API payload into the two-argument overload.

Common situations: Task/case dashboards that filter by user role on cases where the logged-in user id was not resolved (no authenticated principal) before the query was built.

Related errors


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