{"record":{"id":"a29c6c0aabf50965","repo":"flowable/flowable-engine","slug":"type-is-required-when-adding-a-new-task-identity-l-a29c6c","errorCode":null,"errorMessage":"type is required when adding a new task identity link","messagePattern":"type is required when adding a new task identity link","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteIdentityLinkCmd.java","lineNumber":56,"sourceCode":"\n    protected String type;\n\n    public DeleteIdentityLinkCmd(String taskId, String userId, String groupId, String type) {\n        super(taskId);\n        validateParams(userId, groupId, type, taskId);\n        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 FlowableIllegalArgumentException(\"taskId is null\");\n        }\n\n        if (type == null) {\n            throw new FlowableIllegalArgumentException(\"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 FlowableIllegalArgumentException(\"Incompatible usage: cannot use type '\" + type + \"' together with a groupId\");\n            }\n        } else {\n            if (userId == null && groupId == null) {\n                throw new FlowableIllegalArgumentException(\"userId and groupId cannot both be null\");\n            }\n        }\n    }\n\n    @Override\n    protected Void execute(CommandContext commandContext, TaskEntity task) {\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        if (IdentityLinkType.ASSIGNEE.equals(type)) {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteIdentityLinkCmd.java#L38-L74","documentation":"DeleteIdentityLinkCmd.validateParams throws FlowableIllegalArgumentException when the identity link type is null. The type (candidate, assignee, owner, etc.) determines which row is removed, so it is mandatory.","triggerScenarios":"Calling taskService.deleteUserIdentityLink/deleteGroupIdentityLink without supplying a link type, or passing a null type variable through generic identity-link code.","commonSituations":"Building delete calls dynamically where the type string is parsed from config/request input that was omitted; confusing deleteUserIdentityLink's implicit type handling with deleteTaskIdentityLink which requires an explicit type.","solutions":["Pass an explicit type constant such as IdentityLinkType.CANDIDATE or ASSIGNEE.","Validate/normalize user-provided type values before calling the API."],"exampleFix":"// before\ntaskService.deleteTaskIdentityLink(taskId, userId, groupId, null);\n// after\ntaskService.deleteTaskIdentityLink(taskId, userId, groupId, IdentityLinkType.CANDIDATE);","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(type, \"identity link type is required\");","typeGuard":"boolean validType(String type) { return type != null && Set.of(IdentityLinkType.ASSIGNEE, IdentityLinkType.OWNER, IdentityLinkType.CANDIDATE).contains(type); }","tryCatchPattern":"try { taskService.deleteTaskIdentityLink(taskId, userId, groupId, type); } catch (FlowableIllegalArgumentException e) { log.error(\"Missing link type: {}\", e.getMessage()); }","preventionTips":["Always use IdentityLinkType constants instead of raw strings.","Validate user-supplied type values against the known set."],"tags":["cmmn","identity-link","validation","java"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}