flowable/flowable-engine · warning · FlowableIllegalArgumentException
Only one of user or group can be used to create an identity…
Error message
Only one of user or group can be used to create an identity link.
What it means
REST request validation in TaskIdentityLinkCollectionResource.createIdentityLink: the body supplied both a user and a group for a single identity link; an identity link targets exactly one principal type, so the combination is rejected.
Solutions
- Send only one of 'user' or 'group' per request; issue two requests for both
- Clear the other field in the form/model before submitting
- Split user and group assignments into separate API calls
Example fix
// before
{"type": "candidate", "user": "kermit", "group": "management"}
// after
{"type": "candidate", "user": "kermit"}
// plus a second call
{"type": "candidate", "group": "management"} Defensive patterns
Strategy: validation
Validate before calling
if (payload.user && payload.group) {
throw new Error('send only one of user or group per identity link');
} Try / catch
try { ... } catch (e) { if (e.status === 400 && /Only one of user or group/.test(e.body.message)) { splitIntoTwoRequests(); } else { throw e; } } Prevention
- Clear the unused field when switching between user/group modes
- Issue separate requests for user and group links
- Never copy all form fields blindly into the payload
When it happens
Trigger: POST /runtime/tasks/{taskId}/identitylinks with a body containing both fields, e.g. {"type":"candidate","user":"kermit","group":"management"}.
Common situations: UIs that keep the previous selection populated when switching between user/group modes; bulk-merge code that copies all form fields into the payload.
Related errors
- A group or a user is required to create an identity link.
- Identity link family should be 'users' or 'groups'.
- Identity link family should be 'users' or 'groups'.
- 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/2aeb2761d12ba007.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskIdentityLinkCollectionResource.java:75
@ApiOperation(value = "Create an identity link on a task", tags = { "Task Identity Links" }, nickname = "createTaskInstanceIdentityLinks",
notes = "It is possible to add either a user or a group.", code = 201)
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Indicates the task was found and the identity link was created."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found or the task does not have the requested identityLink. The status contains additional information about this error.")
})
@PostMapping(value = "/runtime/tasks/{taskId}/identitylinks", produces = "application/json")
@ResponseStatus(HttpStatus.CREATED)
public RestIdentityLink createIdentityLink(@ApiParam(name = "taskId") @PathVariable("taskId") String taskId, @RequestBody RestIdentityLink identityLink) {
Task task = getTaskFromRequestWithoutAccessCheck(taskId);
if (identityLink.getGroup() == null && identityLink.getUser() == null) {
throw new FlowableIllegalArgumentException("A group or a user is required to create an identity link.");
}
if (identityLink.getGroup() != null && identityLink.getUser() != null) {
throw new FlowableIllegalArgumentException("Only one of user or group can be used to create an identity link.");
}
if (identityLink.getType() == null) {
throw new FlowableIllegalArgumentException("The identity link type is required.");
}
if (restApiInterceptor != null) {
restApiInterceptor.createTaskIdentityLink(task, identityLink);
}
if (identityLink.getGroup() != null) {
taskService.addGroupIdentityLink(task.getId(), identityLink.getGroup(), identityLink.getType());
} else {
taskService.addUserIdentityLink(task.getId(), identityLink.getUser(), identityLink.getType());
}
return restResponseFactory.createRestIdentityLink(identityLink.getType(), identityLink.getUser(), identityLink.getGroup(), task.getId(), null, null);
}View on GitHub (pinned to d6d39ce1c6)