flowable/flowable-engine · error · FlowableIllegalArgumentException
userId and groupId cannot both be null
Error message
userId and groupId cannot both be null
What it means
AddIdentityLinkForCaseInstanceCmd.validateParams throws FlowableIllegalArgumentException when both userId and groupId are null. An identity link must point to at least one principal (user or group); creating one referencing neither would be meaningless, so the command rejects it up front.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AddIdentityLinkForCaseInstanceCmd.java:61
validateParams(caseInstanceId, userId, groupId, type);
this.caseInstanceId = caseInstanceId;
this.userId = userId;
this.groupId = groupId;
this.type = type;
}
protected void validateParams(String caseInstanceId, String userId, String groupId, String type) {
if (caseInstanceId == null) {
throw new FlowableIllegalArgumentException("caseInstanceId is null");
}
if (type == null) {
throw new FlowableIllegalArgumentException("type is required when adding a new case instance identity link");
}
if (userId == null && groupId == null) {
throw new FlowableIllegalArgumentException("userId and groupId cannot both be null");
}
}
@Override
public Void execute(CommandContext commandContext) {
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
CaseInstanceEntityManager caseInstanceEntityManager = cmmnEngineConfiguration.getCaseInstanceEntityManager();
CaseInstanceEntity caseInstance = caseInstanceEntityManager.findById(caseInstanceId);
if (caseInstance == null) {
throw new FlowableObjectNotFoundException("Cannot find case instance with id " + caseInstanceId, CaseInstanceEntity.class);
}
IdentityLinkUtil.createCaseInstanceIdentityLink(caseInstance, userId, groupId, type, cmmnEngineConfiguration);
return null;
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Provide either a userId or a groupId (at least one non-null) when adding the identity link
- Validate user/group presence in caller code before invoking the API
- If the intent was a link to neither, use a different mechanism (e.g. case metadata) instead of an identity link
Example fix
// before cmmnRuntimeService.addIdentityLinkForCaseInstance(caseInstanceId, null, null, "participant"); // after cmmnRuntimeService.addIdentityLinkForCaseInstance(caseInstanceId, "kermit", null, "participant");
Defensive patterns
Strategy: validation
Validate before calling
if (userId == null && groupId == null) throw new IllegalArgumentException("Either userId or groupId must be provided"); Type guard
boolean hasPrincipal(String userId, String groupId) { return userId != null || groupId != null; } Try / catch
try {
cmmnRuntimeService.addIdentityLinkForCaseInstance(caseId, userId, groupId, type);
} catch (FlowableIllegalArgumentException e) {
log.warn("Cannot add identity link: {}", e.getMessage());
} Prevention
- Ensure UI forms require at least one of user or group
- Check variables holding assignee/group are set before linking
- Write a unit test covering both-null input
When it happens
Trigger: Calling addIdentityLinkForCaseInstance (or constructing the command) with type set but both userId and groupId null/omitted — e.g. a REST call supplying only the type, or variables holding the assignee/group both resolving to null.
Common situations: Optional assignee not filled in by the caller; both user and group fields left blank in a UI-driven API request; code intended to add a group link but the group variable was never set.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- type is required when adding a new case instance identity li
- Either set the user id or the group id for an identity link,
- taskId is null
- type is required when adding a new task identity link
- identityId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4acfc27c8392fe1b.
Report an issue: GitHub.