flowable/flowable-engine · error · FlowableIllegalArgumentException
Incompatible usage: cannot use type '' together with a…
Error message
Incompatible usage: cannot use type '' together with a groupId
What it means
DeleteIdentityLinkCmd.validateParams throws FlowableIllegalArgumentException when type is ASSIGNEE or OWNER but a groupId is also supplied. Assignee/owner links apply to a single user only, so combining them with a group is a contradictory request.
Solutions
- Pass groupId = null when the type is ASSIGNEE or OWNER.
- Use a group type (e.g. CANDIDATE) if the link to remove actually targets a group.
Example fix
// before taskService.deleteTaskIdentityLink(taskId, userId, groupId, IdentityLinkType.ASSIGNEE); // after taskService.deleteTaskIdentityLink(taskId, userId, null, IdentityLinkType.ASSIGNEE);
Defensive patterns
Strategy: validation
Validate before calling
if ((IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type)) && groupId != null) { throw new IllegalArgumentException("groupId not allowed for " + type); } Try / catch
try { taskService.deleteTaskIdentityLink(taskId, userId, groupId, type); } catch (FlowableIllegalArgumentException e) { log.error("Incompatible link parameters: {}", e.getMessage()); } Prevention
- Never pass groupId with ASSIGNEE/OWNER types.
- Model assignee/owner removal as user-scoped calls only.
When it happens
Trigger: Calling taskService.deleteTaskIdentityLink with type ASSIGNEE or OWNER and a non-null groupId, e.g. generic link-removal code that always passes both userId and groupId.
Common situations: Refactorings that route all identity-link deletions through one generic method and pass all parameters unconditionally; misunderstanding of which link types are group-scoped.
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
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/916d8641b865a89f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteIdentityLinkCmd.java:62
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 FlowableIllegalArgumentException("taskId is null");
}
if (type == null) {
throw new FlowableIllegalArgumentException("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 FlowableIllegalArgumentException("Incompatible usage: cannot use type '" + type + "' together with a groupId");
}
} else {
if (userId == null && groupId == null) {
throw new FlowableIllegalArgumentException("userId and groupId cannot both be null");
}
}
}
@Override
protected Void execute(CommandContext commandContext, TaskEntity task) {
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
if (IdentityLinkType.ASSIGNEE.equals(type)) {
TaskHelper.changeTaskAssignee(task, null, cmmnEngineConfiguration);
} else if (IdentityLinkType.OWNER.equals(type)) {
TaskHelper.changeTaskOwner(task, null, cmmnEngineConfiguration);
} else {
IdentityLinkUtil.deleteTaskIdentityLinks(task, userId, groupId, type, cmmnEngineConfiguration);
}View on GitHub (pinned to d6d39ce1c6)