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.validateParams() restricts identityIdType to IDENTITY_USER (1) or IDENTITY_GROUP (2). Any other int (e.g. 0, 3) indicates a programming error in how the identity link was categorized, so Flowable throws FlowableIllegalArgumentException.

Solutions

  1. Use the IDENTITY_USER / IDENTITY_GROUP constants instead of raw integers.
  2. Map user-vs-group with a conditional: user links -> 1, group links -> 2.
  3. If wrapping the API, validate the int before delegating.

Example fix

// before
cmd.validateParams(taskId, id, 3, "candidate");
// after
int type = isGroup ? AddIdentityLinkCmd.IDENTITY_GROUP : AddIdentityLinkCmd.IDENTITY_USER;
cmd.validateParams(taskId, id, type, "candidate");
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

boolean isKnownIdentityType(int t) { return t == 1 || t == 2; }

Try / catch

try {
    identityLinkService.validateParams(taskId, id, identityIdType, type);
} catch (FlowableIllegalArgumentException e) {
    log.error("Bad identityIdType: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Internal calls to the identity link service passing an identityIdType int outside {1, 2}, usually from a custom command or wrapper miscalculating the type.

Common situations: Custom code reusing the constants incorrectly; API version differences where a new enum value was mapped to an unexpected int.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

    }

    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) {
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        if (task.getProcessDefinitionId() != null && Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, task.getProcessDefinitionId())) {
            Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();
            compatibilityHandler.addIdentityLink(taskId, identityId, identityIdType, identityType);
            return null;
        }

        String oldAssigneeId = task.getAssignee();
        String oldOwnerId = task.getOwner();
        
        boolean assignedToNoOne = false;
        if (IdentityLinkType.ASSIGNEE.equals(identityType)) {
            

View on GitHub (pinned to d6d39ce1c6)