flowable/flowable-engine · error · FlowableIllegalArgumentException
type is required when adding a new task identity link
Error message
type is required when adding a new task identity link
What it means
AddIdentityLinkCmd requires a non-null identityType (e.g. assignee, owner, participant) to categorize the identity link being added to a task. A null type would produce an ambiguous link, so validateParams throws FlowableIllegalArgumentException.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AddIdentityLinkCmd.java:56
protected String identityType;
public AddIdentityLinkCmd(String taskId, String identityId, int identityIdType, String identityType) {
super(taskId);
validateParams(taskId, identityId, identityIdType, identityType);
this.taskId = taskId;
this.identityId = identityId;
this.identityIdType = identityIdType;
this.identityType = identityType;
}
protected void validateParams(String taskId, String identityId, int identityIdType, String identityType) {
if (taskId == null) {
throw new FlowableIllegalArgumentException("taskId is null");
}
if (identityType == null) {
throw new FlowableIllegalArgumentException("type is required when adding a new task identity link");
}
if (identityId == null && (identityIdType == IDENTITY_GROUP ||
(!IdentityLinkType.ASSIGNEE.equals(identityType) && !IdentityLinkType.OWNER.equals(identityType)))) {
throw new FlowableIllegalArgumentException("identityId is null");
}
if (identityIdType != IDENTITY_USER && identityIdType != IDENTITY_GROUP) {
throw new FlowableIllegalArgumentException("identityIdType allowed values are 1 and 2");
}
}
@Override
protected Void execute(CommandContext commandContext, TaskEntity task) {
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
String oldAssigneeId = task.getAssignee();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a valid IdentityLinkType constant (ASSIGNEE, OWNER, PARTICIPANT, etc.) to the call
- If the type comes from external input, validate/map it to a known IdentityLinkType before invoking
- Default to IdentityLinkType.PARTICIPANT when no specific semantics are needed
Example fix
// before
taskService.addUserIdentityLink(taskId, userId, linkType); // linkType == null
// after
taskService.addUserIdentityLink(taskId, userId,
linkType != null ? linkType : IdentityLinkType.PARTICIPANT); Defensive patterns
Strategy: validation
Validate before calling
if (linkType == null) throw new IllegalArgumentException("identity type is required");
taskService.addUserIdentityLink(taskId, userId, linkType); Type guard
boolean hasType(String type) { return type != null && !type.isBlank(); } Try / catch
try {
taskService.addUserIdentityLink(taskId, userId, type);
} catch (FlowableIllegalArgumentException e) {
log.warn("Invalid identity link call: {}", e.getMessage());
} Prevention
- Use IdentityLinkType constants, never ad-hoc strings or null
- Map external input to known types with a validated lookup
- Default to PARTICIPANT when type is optional
When it happens
Trigger: Calling cmmnTaskService.addUserIdentityLink(taskId, userId, null) or addGroupIdentityLink(taskId, groupId, null), or constructing AddIdentityLinkCmd with a null type argument.
Common situations: Type read from config/property file that is missing, a constant refactored away, passing an enum's null value after a failed lookup, or a REST client omitting the type field.
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
- userId and groupId cannot both be null
- Either set the user id or the group id for an identity link,
- taskId is null
- identityId is null
- identityIdType allowed values are 1 and 2
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/195ae0e0fdc1c4e3.
Report an issue: GitHub.