{"record":{"id":"798ebb939f30ab15","repo":"flowable/flowable-engine","slug":"identity-link-family-should-be-users-or-groups-798ebb","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/TaskIdentityLinkFamilyResource.java","lineNumber":54,"sourceCode":" * @author Frederik Heremans\n */\n@RestController\n@Api(tags = { \"Task Identity Links\" }, authorizations = { @Authorization(value = \"basicAuth\") })\npublic class TaskIdentityLinkFamilyResource extends TaskBaseResource {\n\n    @ApiOperation(value = \"List identity links for a task for either groups or users\", tags = { \"Task Identity Links\" },  nickname = \"listIdentityLinksForFamily\",\n            notes = \"Returns only identity links targeting either users or groups. Response body and status-codes are exactly the same as when getting the full list of identity links for a task.\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the task was found and the requested identity links are returned.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested task was not found.\")\n    })\n    @GetMapping(value = \"/runtime/tasks/{taskId}/identitylinks/{family}\", produces = \"application/json\")\n    public List<RestIdentityLink> getIdentityLinksForFamily(@ApiParam(name = \"taskId\") @PathVariable(\"taskId\") String taskId, @ApiParam(name = \"family\") @PathVariable(\"family\") String family) {\n\n        Task task = getTaskFromRequestWithoutAccessCheck(taskId);\n\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\n        if (restApiInterceptor != null) {\n            restApiInterceptor.accessTaskIdentityLinks(task);\n        }\n\n        boolean isUser = family.equals(RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);\n        List<RestIdentityLink> results = new ArrayList<>();\n\n        List<IdentityLink> allLinks = taskService.getIdentityLinksForTask(task.getId());\n        for (IdentityLink link : allLinks) {\n            boolean match = false;\n            if (isUser) {\n                match = link.getUserId() != null;\n            } else {\n                match = link.getGroupId() != null;\n            }\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskIdentityLinkFamilyResource.java#L36-L72","documentation":"Path-parameter validation in TaskIdentityLinkFamilyResource.getIdentityLinksForFamily: the {family} path segment was neither 'users' nor 'groups', the only two families the endpoint can filter identity links by.","triggerScenarios":"GET /runtime/tasks/{taskId}/identitylinks/{family} where family is not exactly 'users' or 'groups' (e.g. 'user', 'group', 'all', empty).","commonSituations":"Pluralization mistakes in constructed URLs; generic listing code that passes 'all'; older clients using singular segments from other APIs.","solutions":["Use exactly /identitylinks/users or /identitylinks/groups in the URL","Fetch all identity links from GET /runtime/tasks/{taskId}/identitylinks (no family) instead","Normalize/validate the family value before building the URL"],"exampleFix":"// before\nGET /runtime/tasks/123/identitylinks/user\n// after\nGET /runtime/tasks/123/identitylinks/users","handlingStrategy":"validation","validationCode":"const FAMILIES = ['users', 'groups'];\nif (!FAMILIES.includes(family)) {\n  throw new Error(`family must be one of ${FAMILIES.join(', ')}`);\n}","typeGuard":null,"tryCatchPattern":"try { ... } catch (e) { if (e.status === 400 && /Identity link family/.test(e.body.message)) { fixUrlAndRetry(); } else { throw e; } }","preventionTips":["Use the exact plural segments 'users'/'groups'","Reuse URL-builder constants instead of hand-typed strings","Fetch all links from the collection endpoint when family is unknown"],"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-18T11:17:12.947Z"}