flowable/flowable-engine · warning · FlowableIllegalArgumentException
Identity link family should be 'users' or 'groups'.
Error message
Identity link family should be 'users' or 'groups'.
What it means
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.
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
Example fix
// before GET /runtime/tasks/123/identitylinks/user // after GET /runtime/tasks/123/identitylinks/users
Defensive patterns
Strategy: validation
Validate before calling
const FAMILIES = ['users', 'groups'];
if (!FAMILIES.includes(family)) {
throw new Error(`family must be one of ${FAMILIES.join(', ')}`);
} Try / catch
try { ... } catch (e) { if (e.status === 400 && /Identity link family/.test(e.body.message)) { fixUrlAndRetry(); } else { throw e; } } Prevention
- 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
When it happens
Trigger: GET /runtime/tasks/{taskId}/identitylinks/{family} where family is not exactly 'users' or 'groups' (e.g. 'user', 'group', 'all', empty).
Common situations: Pluralization mistakes in constructed URLs; generic listing code that passes 'all'; older clients using singular segments from other APIs.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- A group or a user is required to create an identity link.
- Identity link family should be 'users' or 'groups'.
- Only one of user or group can be used to create an identity…
- The identity link type is required.
- A group or a user is required to create an identity link.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/798ebb939f30ab15.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskIdentityLinkFamilyResource.java:54
* @author Frederik Heremans
*/
@RestController
@Api(tags = { "Task Identity Links" }, authorizations = { @Authorization(value = "basicAuth") })
public class TaskIdentityLinkFamilyResource extends TaskBaseResource {
@ApiOperation(value = "List identity links for a task for either groups or users", tags = { "Task Identity Links" }, nickname = "listIdentityLinksForFamily",
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.")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Indicates the task was found and the requested identity links are returned."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found.")
})
@GetMapping(value = "/runtime/tasks/{taskId}/identitylinks/{family}", produces = "application/json")
public List<RestIdentityLink> getIdentityLinksForFamily(@ApiParam(name = "taskId") @PathVariable("taskId") String taskId, @ApiParam(name = "family") @PathVariable("family") String family) {
Task task = getTaskFromRequestWithoutAccessCheck(taskId);
if (family == null || (!RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family))) {
throw new FlowableIllegalArgumentException("Identity link family should be 'users' or 'groups'.");
}
if (restApiInterceptor != null) {
restApiInterceptor.accessTaskIdentityLinks(task);
}
boolean isUser = family.equals(RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);
List<RestIdentityLink> results = new ArrayList<>();
List<IdentityLink> allLinks = taskService.getIdentityLinksForTask(task.getId());
for (IdentityLink link : allLinks) {
boolean match = false;
if (isUser) {
match = link.getUserId() != null;
} else {
match = link.getGroupId() != null;
}
View on GitHub (pinned to d6d39ce1c6)