{"record":{"id":"195ae0e0fdc1c4e3","repo":"flowable/flowable-engine","slug":"type-is-required-when-adding-a-new-task-identity-l-195ae0","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":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AddIdentityLinkCmd.java","lineNumber":56,"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 FlowableIllegalArgumentException(\"taskId is null\");\n        }\n\n        if (identityType == null) {\n            throw new FlowableIllegalArgumentException(\"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 FlowableIllegalArgumentException(\"identityId is null\");\n        }\n\n        if (identityIdType != IDENTITY_USER && identityIdType != IDENTITY_GROUP) {\n            throw new FlowableIllegalArgumentException(\"identityIdType allowed values are 1 and 2\");\n        }\n    }\n\n    @Override\n    protected Void execute(CommandContext commandContext, TaskEntity task) {\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        \n        String oldAssigneeId = task.getAssignee();","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/AddIdentityLinkCmd.java#L38-L74","documentation":"AddIdentityLinkCmd requires a non-null identityType (e.g. assignee, owner, participant) to categorize the identity link being added to a task. A null type would produce an ambiguous link, so validateParams throws FlowableIllegalArgumentException.","triggerScenarios":"Calling cmmnTaskService.addUserIdentityLink(taskId, userId, null) or addGroupIdentityLink(taskId, groupId, null), or constructing AddIdentityLinkCmd with a null type argument.","commonSituations":"Type read from config/property file that is missing, a constant refactored away, passing an enum's null value after a failed lookup, or a REST client omitting the type field.","solutions":["Pass a valid IdentityLinkType constant (ASSIGNEE, OWNER, PARTICIPANT, etc.) to the call","If the type comes from external input, validate/map it to a known IdentityLinkType before invoking","Default to IdentityLinkType.PARTICIPANT when no specific semantics are needed"],"exampleFix":"// before\ntaskService.addUserIdentityLink(taskId, userId, linkType); // linkType == null\n// after\ntaskService.addUserIdentityLink(taskId, userId,\n    linkType != null ? linkType : IdentityLinkType.PARTICIPANT);","handlingStrategy":"validation","validationCode":"if (linkType == null) throw new IllegalArgumentException(\"identity type is required\");\ntaskService.addUserIdentityLink(taskId, userId, linkType);","typeGuard":"boolean hasType(String type) { return type != null && !type.isBlank(); }","tryCatchPattern":"try {\n    taskService.addUserIdentityLink(taskId, userId, type);\n} catch (FlowableIllegalArgumentException e) {\n    log.warn(\"Invalid identity link call: {}\", e.getMessage());\n}","preventionTips":["Use IdentityLinkType constants, never ad-hoc strings or null","Map external input to known types with a validated lookup","Default to PARTICIPANT when type is optional"],"tags":["cmmn","identity-link","validation","missing-argument"],"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-14T05:17:10.506Z"}