flowable/flowable-engine · error · ActivitiIllegalArgumentException
userId and groupId cannot both be null
Error message
userId and groupId cannot both be null
What it means
AddIdentityLinkForProcessInstanceCmd requires that at least one of userId or groupId is provided; an identity link must reference a user or a group. When both are null, validateParams throws ActivitiIllegalArgumentException.
Solutions
- Provide a userId or a groupId (one of them must be non-null)
- Validate inputs before the call and reject empty user/group pairs
- Check argument order: signature is (processInstanceId, userId, groupId, type)
Example fix
// before
runtimeService.addUserIdentityLinkForProcessInstance(pid, userId, groupId, type); // both null
// after
if (userId == null && groupId == null) {
throw new IllegalArgumentException("userId or groupId required");
}
runtimeService.addUserIdentityLinkForProcessInstance(pid, userId, groupId, type); Defensive patterns
Strategy: validation
Validate before calling
if (userId == null && groupId == null) {
throw new IllegalArgumentException("userId or groupId is required");
} Try / catch
try {
runtimeService.addUserIdentityLinkForProcessInstance(pid, userId, groupId, type);
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().contains("both be null")) {
// reject the request or supply a default identity
} else { throw e; }
} Prevention
- Validate that user/group resolution produced at least one id
- Check the (processInstanceId, userId, groupId, type) argument order
- Reject empty form submissions before they reach the engine
When it happens
Trigger: Calling runtimeService.addUserIdentityLinkForProcessInstance(pid, null, type) with both identifiers absent, or constructing the command with userId == null and groupId == null.
Common situations: Empty form submissions where neither user nor group was filled in; upstream user-directory lookup returned null for both; swapped arguments placing the type where userId should be.
Related errors
- processInstanceId is null
- processInstanceId is null
- type is required when adding a new process instance…
- appDefinitionId is null
- identityId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/8d08497593364aa2.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddIdentityLinkForProcessInstanceCmd.java:57
validateParams(processInstanceId, userId, groupId, type);
this.processInstanceId = processInstanceId;
this.userId = userId;
this.groupId = groupId;
this.type = type;
}
protected void validateParams(String processInstanceId, String userId, String groupId, String type) {
if (processInstanceId == null) {
throw new ActivitiIllegalArgumentException("processInstanceId is null");
}
if (type == null) {
throw new ActivitiIllegalArgumentException("type is required when adding a new process instance identity link");
}
if (userId == null && groupId == null) {
throw new ActivitiIllegalArgumentException("userId and groupId cannot both be null");
}
}
@Override
public Void execute(CommandContext commandContext) {
ExecutionEntity processInstance = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId);
if (processInstance == null) {
throw new ActivitiObjectNotFoundException("Cannot find process instance with id " + processInstanceId, ExecutionEntity.class);
}
processInstance.addIdentityLink(userId, groupId, type);
commandContext.getHistoryManager().createProcessInstanceIdentityLinkComment(processInstanceId, userId, groupId, type, true);
return null;View on GitHub (pinned to d6d39ce1c6)