flowable/flowable-engine · error · FlowableException

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

HistoricIdentityLinkEntityImpl enforces the Flowable invariant that an identity link is either a user assignment or a group assignment, never both. setUserId throws this FlowableException if a groupId is already set and a non-null userId is being assigned. It protects the persistence model from ambiguous historic task assignments.

Solutions

  1. Create two separate identity link entities: one for the groupId and one for the userId.
  2. Call setGroupId(null) before assigning a userId if you truly intend to switch the link type.
  3. Refactor the assignment code to decide up front whether the assignment targets a user or a group.

Example fix

// before
link.setGroupId("management");
link.setUserId("kermit"); // throws

// after
IdentityLinkEntity groupLink = new HistoricIdentityLinkEntityImpl();
groupLink.setGroupId("management");
IdentityLinkEntity userLink = new HistoricIdentityLinkEntityImpl();
userLink.setUserId("kermit");
Defensive patterns

Strategy: validation

Validate before calling

if (link.getGroupId() != null && userId != null) {
    throw new IllegalArgumentException("Use a separate identity link for this user");
}

Try / catch

try {
    link.setUserId(userId);
} catch (FlowableException e) {
    // create a new identity link entity for the user instead
}

Prevention

When it happens

Trigger: Calling setUserId(String) on a HistoricIdentityLinkEntity whose groupId field is already non-null, e.g. after creating a candidate-group link and then trying to also set a user.

Common situations: Custom history/identity-link code that reuses one entity for both group and user assignment; migrating code that assumed both could be set; building historic links manually in tests.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/6f481ee155179836. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-identitylink-service/src/main/java/org/flowable/identitylink/service/impl/persistence/entity/HistoricIdentityLinkEntityImpl.java:76

    @Override
    public String getType() {
        return type;
    }

    @Override
    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String getUserId() {
        return userId;
    }

    @Override
    public void setUserId(String userId) {
        if (this.groupId != null && userId != null) {
            throw new FlowableException("Cannot assign a userId to a task assignment that already has a groupId");
        }
        this.userId = userId;
    }

    @Override
    public String getGroupId() {
        return groupId;
    }

    @Override
    public void setGroupId(String groupId) {
        if (this.userId != null && groupId != null) {
            throw new FlowableException("Cannot assign a groupId to a task assignment that already has a userId");
        }
        this.groupId = groupId;
    }

    @Override

View on GitHub (pinned to d6d39ce1c6)