{"record":{"id":"12afb91857c7bc4c","repo":"flowable/flowable-engine","slug":"identityid-is-null-12afb9","errorCode":null,"errorMessage":"identityId is null","messagePattern":"identityId is null","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddIdentityLinkCmd.java","lineNumber":57,"sourceCode":"        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)) {\n            task.setAssignee(identityId, true, true);\n            assignedToNoOne = identityId == null;\n        } else if (IdentityLinkType.OWNER.equals(identityType)) {\n            task.setOwner(identityId, true);\n        } else if (IDENTITY_USER == identityIdType) {\n            task.addUserIdentityLink(identityId, identityType);","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/AddIdentityLinkCmd.java#L39-L75","documentation":"AddIdentityLinkCmd.validateParams rejects a null identityId unless the link is a group link or an ASSIGNEE/OWNER link (where the id may legitimately be null to unset). Flowable throws ActivitiIllegalArgumentException because the link would reference neither a user nor a group.","triggerScenarios":"Calling taskService.addUserIdentityLink(taskId, null, type) with a non-assignee/owner type; AddIdentityLinkCmd constructed with identityId == null and identityIdType == IDENTITY_USER with a type other than ASSIGNEE/OWNER.","commonSituations":"Swapping the userId and type parameters by mistake; the user id lookup returned null upstream and was passed along; intending to clear an assignee but using a candidate/participant type instead.","solutions":["Pass a non-null userId/groupId, or use type IdentityLinkType.ASSIGNEE or OWNER with null to clear","Use IDENTITY_GROUP (2) as identityIdType if you intended a group link with null user id","Validate the resolved user id before invoking the command"],"exampleFix":"// before\ntaskService.addUserIdentityLink(taskId, userId, IdentityLinkType.CANDIDATE); // userId null\n// after\nif (userId == null) {\n    taskService.setAssignee(taskId, null); // to clear, use assignee\n} else {\n    taskService.addUserIdentityLink(taskId, userId, IdentityLinkType.CANDIDATE);\n}","handlingStrategy":"validation","validationCode":"boolean idMayBeNull = IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type);\nif (identityId == null && !idMayBeNull) {\n    throw new IllegalArgumentException(\"identityId required for type \" + type);\n}","typeGuard":null,"tryCatchPattern":"try {\n    taskService.addUserIdentityLink(taskId, userId, type);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().equals(\"identityId is null\")) {\n        taskService.setAssignee(taskId, null); // clearing via assignee\n    } else { throw e; }\n}","preventionTips":["Remember only ASSIGNEE/OWNER types may have a null identityId","Resolve and validate user ids before passing them on","Do not confuse the userId and type parameter positions"],"tags":["null-argument","identity-link","task","validation"],"backgroundTag":"null-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"}