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
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.
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
Example fix
// before GET /runtime/tasks/123/identitylinks/users/kermit // after GET /runtime/tasks/123/identitylinks/users/kermit/candidate
Defensive patterns
Strategy: validation
Validate before calling
const FAMILIES = ['users', 'groups'];
if (!FAMILIES.includes(family) || !identityId || !type) {
throw new Error('family must be users|groups; identityId and type are required');
} Try / catch
try { ... } catch (e) { if (e.status === 400 && /Identity link family|IdentityId is required|Type is required/.test(e.body.message)) { reportInvalidUrlSegments(); } else { throw e; } } Prevention
- Build URLs with all three segments (family, identityId, type)
- URL-encode path variables
- Centralize the URL template in one helper to avoid missing segments
When it happens
Trigger: GET or DELETE /runtime/tasks/{taskId}/identitylinks/{family}/{identityId}/{type} where family is not 'users'/'groups', identityId is empty, or type is missing/empty.
Common situations: URL-encoding dropping empty path variables; constructed URLs missing the type segment; family pluralization errors as in 3708.
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/c0d57ff05f57ceef.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskIdentityLinkResource.java:97
validateIdentityLinkArguments(family, identityId, type);
// Check if identitylink to delete exists
IdentityLink link = getIdentityLink(family, identityId, type, task.getId());
if (restApiInterceptor != null) {
restApiInterceptor.deleteTaskIdentityLink(task, link);
}
if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family)) {
taskService.deleteUserIdentityLink(task.getId(), identityId, type);
} else {
taskService.deleteGroupIdentityLink(task.getId(), identityId, type);
}
}
protected void validateIdentityLinkArguments(String family, String identityId, String type) {
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 (identityId == null) {
throw new FlowableIllegalArgumentException("IdentityId is required.");
}
if (type == null) {
throw new FlowableIllegalArgumentException("Type is required.");
}
}
protected IdentityLink getIdentityLink(String family, String identityId, String type, String taskId) {
boolean isUser = family.equals(RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);
// Perhaps it would be better to offer getting a single identitylink
// from the API
List<IdentityLink> allLinks = taskService.getIdentityLinksForTask(taskId);
for (IdentityLink link : allLinks) {
boolean rightIdentity = false;
if (isUser) {View on GitHub (pinned to d6d39ce1c6)