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
A HistoricIdentityLinkEntity represents one assignment/identity link on a historic task and must be either user-based or group-based, never both. setUserId rejects assigning a userId when a groupId is already present, since the persisted row would become ambiguous.
Solutions
- Create a separate entity for the user assignment instead of reusing one that already holds a groupId.
- Set groupId to null before calling setUserId if the link really should switch to user-based.
- Distinguish candidate-group links from assignee links in your mapping code: one IdentityLink = one principal type.
Example fix
// before
link.setGroupId("management");
link.setUserId("kermit"); // throws
// after
HistoricIdentityLinkEntity groupLink = ...; groupLink.setGroupId("management");
HistoricIdentityLinkEntity userLink = ...; userLink.setUserId("kermit"); Defensive patterns
Strategy: type-guard
Validate before calling
if (link.getGroupId() != null && userId != null) {
throw new IllegalArgumentException("link already group-based");
} Type guard
function canSetUserId(link) {
return link.getGroupId() == null;
} Try / catch
try {
link.setUserId(userId);
} catch (ActivitiException e) {
link = createNewIdentityLink(); // start a fresh link for the user
link.setUserId(userId);
} Prevention
- One identity link = one principal type (user XOR group)
- Use taskService.addUserIdentityLink/addCandidateGroup instead of entity mutation
- Clear the opposite field before switching link type
When it happens
Trigger: Calling setUserId (directly or via entity manipulation / custom history mapping) on a HistoricIdentityLinkEntity whose groupId field is already non-null and passing a non-null userId.
Common situations: Custom code copying IdentityLink data between entities without clearing the opposite field; history-level configuration or event listeners that mutate identity link entities; data import/migration scripts that reuse an entity for both group and user assignments.
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 groupId to a task assignment that already…
- Cannot assign a userId to a task assignment that already…
- Cannot assign a userId to a task assignment that already…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0eaf9c985784bd88.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/HistoricIdentityLinkEntity.java:115
}
@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)