{"record":{"id":"c0d57ff05f57ceef","repo":"flowable/flowable-engine","slug":"identity-link-family-should-be-users-or-groups-c0d57f","errorCode":null,"errorMessage":"Identity link family should be 'users' or 'groups'.","messagePattern":"Identity link family should be 'users' or 'groups'\\.","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"warning","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskIdentityLinkResource.java","lineNumber":97,"sourceCode":"        validateIdentityLinkArguments(family, identityId, type);\n\n        // Check if identitylink to delete exists\n        IdentityLink link = getIdentityLink(family, identityId, type, task.getId());\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteTaskIdentityLink(task, link);\n        }\n\n        if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family)) {\n            taskService.deleteUserIdentityLink(task.getId(), identityId, type);\n        } else {\n            taskService.deleteGroupIdentityLink(task.getId(), identityId, type);\n        }\n    }\n\n    protected void validateIdentityLinkArguments(String family, String identityId, String type) {\n        if (family == null || (!RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !RestUrls.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 family, String identityId, String type, String taskId) {\n        boolean isUser = family.equals(RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);\n\n        // Perhaps it would be better to offer getting a single identitylink\n        // from the API\n        List<IdentityLink> allLinks = taskService.getIdentityLinksForTask(taskId);\n        for (IdentityLink link : allLinks) {\n            boolean rightIdentity = false;\n            if (isUser) {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskIdentityLinkResource.java#L79-L115","documentation":"Shared argument validator for single identity-link operations (GET/DELETE on /runtime/tasks/{taskId}/identitylinks/{family}/{identityId}/{type}). It rejects a family other than 'users'/'groups', a null identityId, or a null type with FlowableIllegalArgumentException.","triggerScenarios":"GET or DELETE /runtime/tasks/{taskId}/identitylinks/{family}/{identityId}/{type} where family is not 'users'/'groups', identityId is empty, or type is missing/empty.","commonSituations":"URL-encoding dropping empty path variables; constructed URLs missing the type segment; family pluralization errors as in 3708.","solutions":["Build the URL with all three segments, e.g. /identitylinks/users/kermit/candidate","Use only 'users' or 'groups' as the family segment","URL-encode the identityId and type to avoid empty segments"],"exampleFix":"// before\nGET /runtime/tasks/123/identitylinks/users/kermit\n// after\nGET /runtime/tasks/123/identitylinks/users/kermit/candidate","handlingStrategy":"validation","validationCode":"const FAMILIES = ['users', 'groups'];\nif (!FAMILIES.includes(family) || !identityId || !type) {\n  throw new Error('family must be users|groups; identityId and type are required');\n}","typeGuard":null,"tryCatchPattern":"try { ... } catch (e) { if (e.status === 400 && /Identity link family|IdentityId is required|Type is required/.test(e.body.message)) { reportInvalidUrlSegments(); } else { throw e; } }","preventionTips":["Build URLs with all three segments (family, identityId, type)","URL-encode path variables","Centralize the URL template in one helper to avoid missing segments"],"tags":["rest","validation","flowable","identity-links"],"backgroundTag":"invalid-enum-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T16:30:33.424Z"}