flowable/flowable-engine · error · FlowableIllegalArgumentException

identityLinkType is null

Error message

identityLinkType is null

What it means

HistoricProcessInstanceQuery.involvedUser(String userId, String identityLinkType) requires a non-null identityLinkType. Flowable throws FlowableIllegalArgumentException when the type is null, because the identity-link relation must know which link type (e.g. participant, assignee, candidate) to filter on.

Source

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

    }

    @Override
    public HistoricProcessInstanceQuery involvedUser(String involvedUser) {
        if (inOrStatement) {
            this.currentOrQueryObject.involvedUser = involvedUser;
        } else {
            this.involvedUser = involvedUser;
        }
        return this;
    }
    
    @Override
    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) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a valid identity link type string, e.g. IdentityLinkType.PARTICIPANT
  2. Null-check before the call and apply a default type when absent
  3. Validate user-supplied type values against the allowed Flowable identity link types
  4. Drop the involvedUser criterion if no type can be determined

Example fix

// before
query.involvedUser(userId, type); // throws when type == null
// after
query.involvedUser(userId, type != null ? type : IdentityLinkType.PARTICIPANT);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

boolean isValidInvolvedUserArgs(String userId, String type) {
    return userId != null && type != null && !type.trim().isEmpty();
}

Try / catch

try {
    query.involvedUser(userId, identityLinkType);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().equals("identityLinkType is null")) {
        query.involvedUser(userId, IdentityLinkType.PARTICIPANT); // default type
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling involvedUser(userId, null) — e.g. the link type is read from a nullable config field, enum lookup that missed, or a caller simply forgot to pass it.

Common situations: Dynamic query builders parameterizing the link type from user input; mapping tables where a type key had no entry; refactors after renaming IdentityLinkType constants.

Related errors


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