{"record":{"id":"2402f7ecb61e1c3d","repo":"flowable/flowable-engine","slug":"incompatible-usage-cannot-use-type-type-toge-2402f7","errorCode":null,"errorMessage":"Incompatible usage: cannot use type '${type}' together with a groupId","messagePattern":"Incompatible usage: cannot use type '(.+?)' together with a groupId","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteIdentityLinkCmd.java","lineNumber":57,"sourceCode":"        this.taskId = taskId;\n        this.userId = userId;\n        this.groupId = groupId;\n        this.type = type;\n    }\n\n    protected void validateParams(String userId, String groupId, String type, String taskId) {\n        if (taskId == null) {\n            throw new ActivitiIllegalArgumentException(\"taskId is null\");\n        }\n\n        if (type == null) {\n            throw new ActivitiIllegalArgumentException(\"type is required when adding a new task identity link\");\n        }\n\n        // Special treatment for assignee and owner: group cannot be used and userId may be null\n        if (IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type)) {\n            if (groupId != null) {\n                throw new ActivitiIllegalArgumentException(\"Incompatible usage: cannot use type '\" + type\n                        + \"' together with a groupId\");\n            }\n        } else {\n            if (userId == null && groupId == null) {\n                throw new ActivitiIllegalArgumentException(\"userId and groupId cannot both be null\");\n            }\n        }\n    }\n\n    @Override\n    protected Void execute(CommandContext commandContext, TaskEntity task) {\n\n        if (IdentityLinkType.ASSIGNEE.equals(type)) {\n            task.setAssignee(null, true, true);\n        } else if (IdentityLinkType.OWNER.equals(type)) {\n            task.setOwner(null, true);\n        } else {\n            task.deleteIdentityLink(userId, groupId, type);","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteIdentityLinkCmd.java#L39-L75","documentation":"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.","triggerScenarios":"Calling taskService.deleteGroupIdentityLink(taskId, groupId, IdentityLinkType.ASSIGNEE or OWNER) — i.e. any delete that supplies a groupId while type is ASSIGNEE/OWNER.","commonSituations":"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.","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."],"exampleFix":"// before\ntaskService.deleteGroupIdentityLink(taskId, groupId, IdentityLinkType.ASSIGNEE);\n// after\ntaskService.deleteUserIdentityLink(taskId, userId, IdentityLinkType.ASSIGNEE);","handlingStrategy":"validation","validationCode":"if ((IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type))\n        && groupId != null) {\n    throw new IllegalArgumentException(type + \" cannot be combined with a groupId\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    deleteIdentityLink(taskId, userId, groupId, type);\n} catch (ActivitiIllegalArgumentException e) {\n    log.warn(\"Incompatible identity-link arguments: {}\", e.getMessage());\n}","preventionTips":["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"],"tags":["identity-link","invalid-argument-combination","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}