{"record":{"id":"04789e9907caa99d","repo":"flowable/flowable-engine","slug":"identity-link-family-should-be-users-or-groups-04789e","errorCode":null,"errorMessage":"Identity link family should be 'users' or 'groups'.","messagePattern":"Identity link family should be 'users' or 'groups'\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceIdentityLinkResource.java","lineNumber":102,"sourceCode":"        validateIdentityLinkArguments(family, identityId, type);\n\n        IdentityLink link = getIdentityLink(identityId, family, type, caseInstance.getId());\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteCaseInstanceIdentityLink(caseInstance, link);\n        }\n\n        if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family)) {\n            runtimeService.deleteGroupIdentityLink(caseInstance.getId(), identityId, type);\n            \n        } else {\n            runtimeService.deleteUserIdentityLink(caseInstance.getId(), identityId, type);\n        }\n    }\n\n    protected void validateIdentityLinkArguments(String family, String identityId, String type) {\n        if (family == null || (!CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family))) {\n            throw new FlowableIllegalArgumentException(\"Identity link family should be 'users' or 'groups'.\");\n        }\n        if (identityId == null) {\n            throw new FlowableIllegalArgumentException(\"IdentityId is required.\");\n        }\n        if (type == null) {\n            throw new FlowableIllegalArgumentException(\"Type is required.\");\n        }\n    }\n\n    protected IdentityLink getIdentityLink(String identityId, String family, String type, String caseInstanceId) {\n        // Perhaps it would be better to offer getting a single identity link\n        // from the API\n        List<IdentityLink> allLinks = runtimeService.getIdentityLinksForCaseInstance(caseInstanceId);\n        for (IdentityLink link : allLinks) {\n            if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family) && identityId.equals(link.getUserId()) && link.getType().equals(type)) {\n                return link;\n            \n            } else if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && identityId.equals(link.getGroupId()) && link.getType().equals(type)) {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceIdentityLinkResource.java#L84-L120","documentation":"validateIdentityLinkArguments checks the URL path segment selecting the identity-link family. It must be exactly 'users' or 'groups' (the CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_* constants); anything else throws FlowableIllegalArgumentException(\"Identity link family should be 'users' or 'groups'.\").","triggerScenarios":"GET or DELETE /cmmn-runtime/case-instances/{id}/identitylinks/{family}/{identityId}/{type} where {family} is not 'users' or 'groups' — e.g. 'user', 'group', 'members', or a typo.","commonSituations":"Singular/plural mix-ups in hand-built URLs; confusing this endpoint with task identity-links paths; case-sensitivity mistakes ('Users').","solutions":["Use the exact path segments 'users' or 'groups' in the URL.","Build URLs with CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS / _GROUPS constants instead of string literals.","Fix typos and ensure lowercase segments."],"exampleFix":"// before\nDELETE /cmmn-runtime/case-instances/case-1/identitylinks/user/kermit/participant\n// after\nDELETE /cmmn-runtime/case-instances/case-1/identitylinks/users/kermit/participant","handlingStrategy":"validation","validationCode":"// Java\nif (!\"users\".equals(family) && !\"groups\".equals(family)) {\n    throw new IllegalArgumentException(\"family must be users or groups\");\n}","typeGuard":null,"tryCatchPattern":"try { restTemplate.exchange(url, HttpMethod.DELETE, null, Void.class, vars); }\ncatch (HttpClientErrorException e) { /* 400: family must be users or groups */ }","preventionTips":["Build URLs from CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_* constants","Use plural lowercase segments","Centralize identity-link URL construction in one helper"],"tags":["rest-api","identity-link","url-path","validation"],"backgroundTag":"invalid-argument-value","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"}