{"record":{"id":"2b38b0bc862665cc","repo":"flowable/flowable-engine","slug":"type-is-required-when-adding-a-new-task-identity-l-2b38b0","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":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddIdentityLinkCmd.java","lineNumber":51,"sourceCode":"\n    protected String identityType;\n\n    public AddIdentityLinkCmd(String taskId, String identityId, int identityIdType, String identityType) {\n        super(taskId);\n        validateParams(taskId, identityId, identityIdType, identityType);\n        this.taskId = taskId;\n        this.identityId = identityId;\n        this.identityIdType = identityIdType;\n        this.identityType = identityType;\n    }\n\n    protected void validateParams(String taskId, String identityId, int identityIdType, String identityType) {\n        if (taskId == null) {\n            throw new ActivitiIllegalArgumentException(\"taskId is null\");\n        }\n\n        if (identityType == null) {\n            throw new ActivitiIllegalArgumentException(\"type is required when adding a new task identity link\");\n        }\n\n        if (identityId == null && (identityIdType == IDENTITY_GROUP ||\n                (!IdentityLinkType.ASSIGNEE.equals(identityType) && !IdentityLinkType.OWNER.equals(identityType)))) {\n\n            throw new ActivitiIllegalArgumentException(\"identityId is null\");\n        }\n\n        if (identityIdType != IDENTITY_USER && identityIdType != IDENTITY_GROUP) {\n            throw new ActivitiIllegalArgumentException(\"identityIdType allowed values are 1 and 2\");\n        }\n    }\n\n    @Override\n    protected Void execute(CommandContext commandContext, TaskEntity task) {\n\n        boolean assignedToNoOne = false;\n        if (IdentityLinkType.ASSIGNEE.equals(identityType)) {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddIdentityLinkCmd.java#L33-L69","documentation":"AddIdentityLinkCmd adds an identity link (user/group association) to a task. Before executing, validateParams checks that the identity link 'type' (e.g. assignee, candidate, owner) is non-null. Flowable throws ActivitiIllegalArgumentException because an identity link without a type is meaningless and cannot be persisted.","triggerScenarios":"Calling taskService.addUserIdentityLink(taskId, userId, null), taskService.addGroupIdentityLink with a null type, or constructing AddIdentityLinkCmd directly with type == null.","commonSituations":"Passing a variable holding the link type that was never initialized; reading the type from config/JSON where the key is missing; confusion between identityId and identityType parameters due to similar names.","solutions":["Pass a valid IdentityLinkType constant (ASSIGNEE, OWNER, CANDIDATE, PARTICIPANT) as the type argument","Check the type variable for null before calling addIdentityLink","If the type comes from external input, default to IdentityLinkType.CANDIDATE or reject the request early"],"exampleFix":"// before\ntaskService.addUserIdentityLink(taskId, userId, linkType); // linkType is null\n// after\nString type = linkType != null ? linkType : IdentityLinkType.CANDIDATE;\ntaskService.addUserIdentityLink(taskId, userId, type);","handlingStrategy":"validation","validationCode":"if (taskId == null || linkType == null) {\n    throw new IllegalArgumentException(\"taskId and linkType are required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    taskService.addUserIdentityLink(taskId, userId, linkType);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"type is required\")) {\n        taskService.addUserIdentityLink(taskId, userId, IdentityLinkType.CANDIDATE);\n    } else { throw e; }\n}","preventionTips":["Always use IdentityLinkType constants instead of raw strings","Null-check optional inputs before invoking engine commands","Validate at the API/service boundary before reaching the engine"],"tags":["null-argument","identity-link","task","validation"],"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-18T11:17:12.947Z"}