flowable/flowable-engine · error · FlowableIllegalArgumentException
userId is null
Error message
userId is null
What it means
HistoricProcessInstanceQuery.involvedUser(String userId, String identityLinkType) requires a non-null userId. Flowable throws FlowableIllegalArgumentException when userId is null because an identity-link filter without a user is meaningless. Validation is fail-fast at query-build time.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java:606
this.activeActivityIds = activityIds;
}
return this;
}
@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) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a non-null userId string to involvedUser
- Null-check the userId first and skip the involvedUser criterion or use a different query when absent
- Resolve the user identity upstream (e.g. require authentication) before building the query
- If the intent is to query regardless of user, drop this criterion entirely
Example fix
// before
query.involvedUser(userId, IdentityLinkType.PARTICIPANT); // throws when userId == null
// after
if (userId != null) {
query.involvedUser(userId, IdentityLinkType.PARTICIPANT);
} Defensive patterns
Strategy: validation
Validate before calling
if (userId == null) {
throw new IllegalArgumentException("userId is required for involvedUser filter");
}
query.involvedUser(userId, IdentityLinkType.PARTICIPANT); Type guard
boolean isValidUserId(String userId) {
return userId != null && !userId.trim().isEmpty();
} Try / catch
try {
query.involvedUser(userId, identityLinkType);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().equals("userId is null")) {
// fall back to a query without the involvedUser criterion
} else {
throw e;
}
} Prevention
- Resolve the current user (auth context) before building user-scoped queries
- Make userId a required, validated parameter in service methods
- Never forward nullable request parameters into Flowable query criteria
- Add null-checks in query-builder wrapper methods
When it happens
Trigger: Calling involvedUser(null, identityLinkType) — e.g. the userId comes from a nullable authenticated-user context, request parameter, or variable that was never assigned.
Common situations: Web controllers passing SecurityContext-derived usernames that are null for anonymous users; service methods forwarding optional user arguments; refactors that removed a default user value.
Related errors
- identityLinkType is null
- groupId is null
- involvedGroups are null
- userId is null
- identityLinkType is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/9f5afbf132d0c8be.
Report an issue: GitHub.