flowable/flowable-engine · error · FlowableIllegalArgumentException

identityIdType allowed values are 1 and 2

Error message

identityIdType allowed values are 1 and 2

What it means

AddIdentityLinkCmd's identityIdType parameter must be IDENTITY_USER (1) or IDENTITY_GROUP (2); any other int is rejected with FlowableIllegalArgumentException because the engine cannot determine what kind of identity the link refers to.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AddIdentityLinkCmd.java:66

    }

    protected void validateParams(String taskId, String identityId, int identityIdType, String identityType) {
        if (taskId == null) {
            throw new FlowableIllegalArgumentException("taskId is null");
        }

        if (identityType == null) {
            throw new FlowableIllegalArgumentException("type is required when adding a new task identity link");
        }

        if (identityId == null && (identityIdType == IDENTITY_GROUP ||
                (!IdentityLinkType.ASSIGNEE.equals(identityType) && !IdentityLinkType.OWNER.equals(identityType)))) {

            throw new FlowableIllegalArgumentException("identityId is null");
        }

        if (identityIdType != IDENTITY_USER && identityIdType != IDENTITY_GROUP) {
            throw new FlowableIllegalArgumentException("identityIdType allowed values are 1 and 2");
        }
    }

    @Override
    protected Void execute(CommandContext commandContext, TaskEntity task) {
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        
        String oldAssigneeId = task.getAssignee();
        String oldOwnerId = task.getOwner();
        
        boolean assignedToNoOne = false;
        if (IdentityLinkType.ASSIGNEE.equals(identityType)) {
            
            if (oldAssigneeId == null && identityId == null) {
                return null;
            }
            
            if (oldAssigneeId != null && oldAssigneeId.equals(identityId)) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Use the constants AddIdentityLinkCmd.IDENTITY_USER (1) / IDENTITY_GROUP (2) instead of raw literals
  2. Map your enum to the engine constants in one place with validation
  3. Prefer the higher-level TaskService methods (addUserIdentityLink / addGroupIdentityLink) which set the correct type automatically

Example fix

// before
new AddIdentityLinkCmd(taskId, identityId, 3, type);
// after
new AddIdentityLinkCmd(taskId, identityId, AddIdentityLinkCmd.IDENTITY_GROUP, type);
Defensive patterns

Strategy: validation

Validate before calling

if (identityIdType != 1 && identityIdType != 2) throw new IllegalArgumentException("identityIdType must be 1 (user) or 2 (group)");

Type guard

boolean isValidIdentityIdType(int t) { return t == AddIdentityLinkCmd.IDENTITY_USER || t == AddIdentityLinkCmd.IDENTITY_GROUP; }

Try / catch

try {
    new AddIdentityLinkCmd(taskId, identityId, identityIdType, type).execute(ctx);
} catch (FlowableIllegalArgumentException e) {
    log.error("Bad identityIdType: use IDENTITY_USER/IDENTITY_GROUP constants", e);
}

Prevention

When it happens

Trigger: Constructing AddIdentityLinkCmd (or calling internal APIs) with identityIdType values like 0, 3, or an uninitialized int, or passing a boolean/other mapping mistakenly as the type int.

Common situations: Custom API wrappers computing the type with wrong constants, off-by-one enum-to-int mapping, deserialization defaulting the field to 0.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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