flowable/flowable-engine · error · ActivitiIllegalArgumentException
Incompatible usage: cannot use type
Error message
Incompatible usage: cannot use type '${type}' together with a groupId What it means
Identity link types ASSIGNEE and OWNER are user-scoped by design: they always reference a single user and can never point to a group. If such a type is supplied together with a groupId, validateParams rejects the combination with ActivitiIllegalArgumentException as an incompatible usage.
Solutions
- Use deleteUserIdentityLink with the userId when type is ASSIGNEE or OWNER.
- Only pass groupId for group-capable types (e.g. CANDIDATE); pass null groupId otherwise.
- Fix generic helper methods to route to the correct delete method based on type.
Example fix
// before taskService.deleteGroupIdentityLink(taskId, groupId, IdentityLinkType.ASSIGNEE); // after taskService.deleteUserIdentityLink(taskId, userId, IdentityLinkType.ASSIGNEE);
Defensive patterns
Strategy: validation
Validate before calling
if ((IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type))
&& groupId != null) {
throw new IllegalArgumentException(type + " cannot be combined with a groupId");
} Try / catch
try {
deleteIdentityLink(taskId, userId, groupId, type);
} catch (ActivitiIllegalArgumentException e) {
log.warn("Incompatible identity-link arguments: {}", e.getMessage());
} Prevention
- Route ASSIGNEE/OWNER deletions to the user-based API
- Write a single helper that picks userId vs groupId based on type
- Document that candidate-group links and assignee links are different concepts
When it happens
Trigger: Calling taskService.deleteGroupIdentityLink(taskId, groupId, IdentityLinkType.ASSIGNEE or OWNER) — i.e. any delete that supplies a groupId while type is ASSIGNEE/OWNER.
Common situations: Generic identity-link removal helpers that forward both userId and groupId plus a type without narrowing per type; refactoring add-link code to delete-link code keeping the wrong parameter; confusion between candidate groups and assignee semantics.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- A group or a user is required to create an identity link.
- A group or a user is required to create an identity link.
- A group or a user is required to create an identity link.
- appDefinitionId is null
- Either set the user id or the group id for an identity…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2402f7ecb61e1c3d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteIdentityLinkCmd.java:57
this.taskId = taskId;
this.userId = userId;
this.groupId = groupId;
this.type = type;
}
protected void validateParams(String userId, String groupId, String type, String taskId) {
if (taskId == null) {
throw new ActivitiIllegalArgumentException("taskId is null");
}
if (type == null) {
throw new ActivitiIllegalArgumentException("type is required when adding a new task identity link");
}
// Special treatment for assignee and owner: group cannot be used and userId may be null
if (IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type)) {
if (groupId != null) {
throw new ActivitiIllegalArgumentException("Incompatible usage: cannot use type '" + type
+ "' together with a groupId");
}
} else {
if (userId == null && groupId == null) {
throw new ActivitiIllegalArgumentException("userId and groupId cannot both be null");
}
}
}
@Override
protected Void execute(CommandContext commandContext, TaskEntity task) {
if (IdentityLinkType.ASSIGNEE.equals(type)) {
task.setAssignee(null, true, true);
} else if (IdentityLinkType.OWNER.equals(type)) {
task.setOwner(null, true);
} else {
task.deleteIdentityLink(userId, groupId, type);View on GitHub (pinned to d6d39ce1c6)