{"record":{"id":"957ad3b8206da0e7","repo":"flowable/flowable-engine","slug":"userid-and-groupid-cannot-both-be-null-957ad3","errorCode":null,"errorMessage":"userId and groupId cannot both be null","messagePattern":"userId and groupId cannot both be null","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":66,"sourceCode":"    }\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)) {\n            TaskHelper.changeTaskAssignee(task, null, cmmnEngineConfiguration);\n        } else if (IdentityLinkType.OWNER.equals(type)) {\n            TaskHelper.changeTaskOwner(task, null, cmmnEngineConfiguration);\n        } else {\n            IdentityLinkUtil.deleteTaskIdentityLinks(task, userId, groupId, type, cmmnEngineConfiguration);\n        }\n\n        return null;\n    }\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteIdentityLinkCmd.java#L48-L84","documentation":"DeleteIdentityLinkCmd.validateParams throws FlowableIllegalArgumentException when, for a non-assignee/owner type, both userId and groupId are null. Without at least one identity, there is no link to identify and delete.","triggerScenarios":"Calling taskService.deleteTaskIdentityLink with a type like CANDIDATE but null userId and null groupId, e.g. when both came from optional request fields.","commonSituations":"REST/service layers with optional parameters silently forwarding nulls; cleanup jobs iterating link data where fields were never populated.","solutions":["Provide either the userId or the groupId of the link to remove.","Guard at the call site: require at least one non-null identity before invoking the delete."],"exampleFix":"// before\ntaskService.deleteTaskIdentityLink(taskId, null, null, IdentityLinkType.CANDIDATE);\n// after\nif (userId == null && groupId == null) throw new IllegalArgumentException(\"userId or groupId required\");\ntaskService.deleteTaskIdentityLink(taskId, userId, groupId, IdentityLinkType.CANDIDATE);","handlingStrategy":"validation","validationCode":"if (userId == null && groupId == null) throw new IllegalArgumentException(\"userId or groupId required\");","typeGuard":null,"tryCatchPattern":"try { taskService.deleteTaskIdentityLink(taskId, userId, groupId, type); } catch (FlowableIllegalArgumentException e) { log.error(\"Identity link delete requires userId or groupId\"); }","preventionTips":["Require at least one identity parameter in API layers.","Reject empty/blank strings the same as null."],"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"}