{"record":{"id":"8aac49372d0fe870","repo":"flowable/flowable-engine","slug":"either-set-the-user-id-or-the-group-id-for-an-iden","errorCode":null,"errorMessage":"Either set the user id or the group id for an identity link, but not both the same time.","messagePattern":"Either set the user id or the group id for an identity link, but not both the same time\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractCaseInstanceIdentityLinkCmd.java","lineNumber":78,"sourceCode":"    /**\n     * Creates a new identity link entry for the given case instance, which can either be a user or group based one, but not both the same time.\n     * If both the user and group ids are null, no new identity link is created.\n     *\n     * @param commandContext the command context within which to perform the identity link creation\n     * @param caseInstanceId the id of the case instance to create an identity link for\n     * @param userId the user id if this is a user based identity link, otherwise null\n     * @param groupId the group id if this is a group based identity link, otherwise null\n     * @param identityType the type of identity link (e.g. owner or assignee, etc)\n     */\n    protected void createIdentityLinkType(CommandContext commandContext, String caseInstanceId, String userId, String groupId, String identityType) {\n        // if both user and group ids are null, don't create an identity link\n        if (userId == null && groupId == null) {\n            return;\n        }\n\n        // if both are set the same time, throw an exception as this is not allowed\n        if (userId != null && groupId != null) {\n            throw new FlowableIllegalArgumentException(\"Either set the user id or the group id for an identity link, but not both the same time.\");\n        }\n\n        CaseInstanceEntity caseInstanceEntity = getCaseInstanceEntity(commandContext, caseInstanceId);\n        IdentityLinkUtil.createCaseInstanceIdentityLink(caseInstanceEntity, userId, groupId, identityType,\n            CommandContextUtil.getCmmnEngineConfiguration(commandContext));\n    }\n}\n\n","sourceCodeStart":60,"sourceCodeEnd":87,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractCaseInstanceIdentityLinkCmd.java#L60-L87","documentation":"A case instance identity link command was given both a userId and a groupId. Flowable identity links attach to exactly one principal, so both being set is rejected up front with FlowableIllegalArgumentException.","triggerScenarios":"createIdentityLinkType invoked with non-null userId AND non-null groupId, e.g. programmatically passing both when constructing the command via CaseService identity link APIs.","commonSituations":"Variables or config where user and group both populated; merging code paths that set defaults for both; form input that captures both fields without validation.","solutions":["Validate input so exactly one of userId/groupId is set before calling the identity link API","Call the API twice — once with userId, once with groupId — if both principals genuinely need the link","Null out the unused field in your service layer before issuing the command"],"exampleFix":"// before\ncmmnRuntimeService.addIdentityLink(caseInstanceId, userId, groupId, \"participant\"); // both set\n// after\nif (userId != null) {\n    cmmnRuntimeService.addUserIdentityLink(caseInstanceId, userId, \"participant\");\n} else if (groupId != null) {\n    cmmnRuntimeService.addGroupIdentityLink(caseInstanceId, groupId, \"participant\");\n}","handlingStrategy":"validation","validationCode":"if (userId != null && groupId != null) throw new Error('provide either userId or groupId, not both');","typeGuard":"function exactlyOnePrincipal(userId, groupId) { return (userId == null) !== (groupId == null); }","tryCatchPattern":"try { addIdentityLink(...); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().startsWith('Either set the user id')) sanitizeInput(); else throw e; }","preventionTips":["Validate principal inputs at the API boundary","Model identity link targets as a discriminated union (user OR group)","Never default both userId and groupId from form/config data"],"tags":["cmmn","identity-link","validation"],"backgroundTag":"mutually-exclusive-options","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"}