flowable/flowable-engine · error · ActivitiException
Cannot assign a userId to a task assignment that already…
Error message
Cannot assign a userId to a task assignment that already has a groupId
What it means
Same invariant as the historic variant but for runtime IdentityLinkEntity: a runtime identity link is either user- or group-based. setUserId throws ActivitiException when groupId is already set and a non-null userId is assigned.
Solutions
- Add a new IdentityLinkEntity for the assignee instead of reusing the candidate-group link; use taskService.addUserIdentityLink / setAssignee.
- Clear groupId first if intentionally converting the link to user-based.
- Keep candidate groups and assignees as distinct links — that is how the API and UI expect them.
Example fix
// before
IdentityLinkEntity link = ...; link.setGroupId("management"); link.setUserId("kermit"); // throws
// after
taskService.addCandidateGroup(taskId, "management");
taskService.setAssignee(taskId, "kermit"); Defensive patterns
Strategy: validation
Validate before calling
if (link.getGroupId() != null && userId != null) {
throw new IllegalArgumentException("cannot assign user to group-based link");
} Type guard
function isUserLinkAssignable(link) {
return link.getGroupId() == null;
} Try / catch
try {
taskService.addUserIdentityLink(taskId, userId, IdentityLinkType.CANDIDATE);
} catch (ActivitiException e) {
log.warn("Link conflict on task {}: {}", taskId, e.getMessage());
} Prevention
- Use taskService.setAssignee/addCandidateGroup instead of touching entities
- Model candidate group and assignee as separate links
- Review TaskListener code for mixed principal assignments
When it happens
Trigger: Calling setUserId on a runtime IdentityLinkEntity (e.g., task candidate/assignee links) that already has a groupId set; custom task listeners or assignment code mutating one entity for both a candidate group and an assignee.
Common situations: TaskListener/assignment handler code that adds both candidateGroup and assignee to the same IdentityLinkEntity object; custom REST/API layers building identity links from mixed request payloads; migration tools converting candidate groups to user assignments in place.
Related errors
- Cannot assign a groupId to a task assignment that already…
- Cannot assign a groupId to a task assignment that already…
- Cannot assign a userId to a task assignment that already…
- identityId is null
- task not found
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7ae7ddda14f3fe61.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/IdentityLinkEntity.java:137
}
@Override
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
if (this.groupId != null && userId != null) {
throw new ActivitiException("Cannot assign a userId to a task assignment that already has a groupId");
}
this.userId = userId;
}
@Override
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
if (this.userId != null && groupId != null) {
throw new ActivitiException("Cannot assign a groupId to a task assignment that already has a userId");
}
this.groupId = groupId;
}
@Override
public String getTaskId() {View on GitHub (pinned to d6d39ce1c6)