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

  1. Use deleteUserIdentityLink with the userId when type is ASSIGNEE or OWNER.
  2. Only pass groupId for group-capable types (e.g. CANDIDATE); pass null groupId otherwise.
  3. 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

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


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)