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

IdentityLinkEntityImpl.setUserId enforces the same user-vs-group exclusivity for runtime identity links: if the entity's groupId is already set, assigning a non-null userId throws this FlowableException. It is called by engine code such as getDefaultIdentityLinks when resolving default task identity links.

Solutions

  1. Ensure each identity link entity represents exactly one assignment: split user and group links into separate entities.
  2. Check the process definition so candidateGroup and candidateUser are declared as distinct candidate entries, not merged.
  3. Clear groupId (setGroupId(null)) before setting a userId when intentionally converting the link.

Example fix

// before
identityLink.setGroupId("sales");
identityLink.setUserId("kermit"); // throws

// after
IdentityLinkEntity groupLink = createLink("sales", null);
IdentityLinkEntity userLink = createLink(null, "kermit");
Defensive patterns

Strategy: validation

Validate before calling

if (identityLink.getGroupId() != null && userId != null) {
    throw new IllegalArgumentException("Split user and group into separate identity links");
}

Try / catch

try {
    identityLink.setUserId(userId);
} catch (FlowableException e) {
    // fall back to creating a fresh IdentityLinkEntity for the user
}

Prevention

When it happens

Trigger: Engine resolution of default identity links (getDefaultIdentityLinks) or direct API calls setting a userId on a runtime IdentityLinkEntity that already carries a groupId; typically caused by a task/definition configured with both candidate group and candidate user data colliding into one entity.

Common situations: BPMN task definitions with misconfigured candidateUser and candidateGroup on the same link; custom identity-link providers that populate both fields; programmatic assignment code written against older Flowable versions that tolerated both fields.

Related errors


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

Appendix: source

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

    @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)