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
- Pass a valid identity link type string, e.g. IdentityLinkType.PARTICIPANT
- Null-check before the call and apply a default type when absent
- Validate user-supplied type values against the allowed Flowable identity link types
- 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
- Default identity link types with constants from IdentityLinkType
- Validate user-supplied link-type strings against supported values
- Centralize involvedUser calls in helpers that apply defaults
- Cover link-type parameterization with unit tests
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.