flowable/flowable-engine · error · ActivitiIllegalArgumentException
userId and groupId cannot both be null
Error message
userId and groupId cannot both be null
What it means
Parameter validation in AddIdentityLinkForProcessDefinitionCmd.validateParams: an identity link needs at least one target, so userId and groupId may not both be null (processDefinitionId null is checked in the same helper).
Solutions
- Provide either a userId or a groupId — at least one must be non-null
- Validate the input before calling; reject requests with no user and no group
- If removal is the goal, use the corresponding delete/remove identity link API instead
Example fix
// before
repositoryService.addGroupIdentityLinkForProcessDefinition(defId, groupId); // groupId null
// after
if (groupId == null && userId == null) {
throw new IllegalArgumentException("Provide userId or groupId");
}
repositoryService.addGroupIdentityLinkForProcessDefinition(defId, groupId); Defensive patterns
Strategy: validation
Validate before calling
if (userId == null && groupId == null) {
throw new IllegalArgumentException("At least one of userId or groupId must be provided");
} Try / catch
try {
repositoryService.addIdentityLinkForProcessDefinition(defId, userId, groupId, type);
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().contains("both be null")) {
// reject or supply a default group
} else { throw e; }
} Prevention
- Reject form/REST payloads that omit both user and group
- Provide a fallback default group for unassigned links
- Use remove/delete APIs for un-linking, not the add command with nulls
When it happens
Trigger: Calling repositoryService.addUserIdentityLinkForProcessDefinition(id, null) (userId overload with null) or constructing the command with both userId and groupId null.
Common situations: Both user and group variables were resolved from empty configuration or a form with unfilled fields; a refactor removed the default group id; intending to delete a link but using the add command.
Related errors
- processDefinitionId is null
- processDefinitionId is null
- userId and groupId cannot both be null
- appDefinitionId is null
- identityId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/35b21f7ecb8c3c10.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddIdentityLinkForProcessDefinitionCmd.java:50
protected String userId;
protected String groupId;
public AddIdentityLinkForProcessDefinitionCmd(String processDefinitionId, String userId, String groupId) {
validateParams(userId, groupId, processDefinitionId);
this.processDefinitionId = processDefinitionId;
this.userId = userId;
this.groupId = groupId;
}
protected void validateParams(String userId, String groupId, String processDefinitionId) {
if (processDefinitionId == null) {
throw new ActivitiIllegalArgumentException("processDefinitionId is null");
}
if (userId == null && groupId == null) {
throw new ActivitiIllegalArgumentException("userId and groupId cannot both be null");
}
}
@Override
public Void execute(CommandContext commandContext) {
ProcessDefinitionEntity processDefinition = commandContext
.getProcessDefinitionEntityManager()
.findProcessDefinitionById(processDefinitionId);
if (processDefinition == null) {
throw new ActivitiObjectNotFoundException("Cannot find process definition with id " + processDefinitionId, ProcessDefinition.class);
}
processDefinition.addIdentityLink(userId, groupId);
return null;
}
View on GitHub (pinned to d6d39ce1c6)