flowable/flowable-engine · error · FlowableIllegalArgumentException

type is required when adding a new task identity link

Error message

type is required when adding a new task identity link

What it means

DeleteIdentityLinkCmd.validateParams throws FlowableIllegalArgumentException when the identity link type is null. The type (candidate, assignee, owner, etc.) determines which row is removed, so it is mandatory.

Source

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

    protected String type;

    public DeleteIdentityLinkCmd(String taskId, String userId, String groupId, String type) {
        super(taskId);
        validateParams(userId, groupId, type, taskId);
        this.taskId = taskId;
        this.userId = userId;
        this.groupId = groupId;
        this.type = type;
    }

    protected void validateParams(String userId, String groupId, String type, String taskId) {
        if (taskId == null) {
            throw new FlowableIllegalArgumentException("taskId is null");
        }

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

        // Special treatment for assignee and owner: group cannot be used and userId may be null
        if (IdentityLinkType.ASSIGNEE.equals(type) || IdentityLinkType.OWNER.equals(type)) {
            if (groupId != null) {
                throw new FlowableIllegalArgumentException("Incompatible usage: cannot use type '" + type + "' together with a groupId");
            }
        } else {
            if (userId == null && groupId == null) {
                throw new FlowableIllegalArgumentException("userId and groupId cannot both be null");
            }
        }
    }

    @Override
    protected Void execute(CommandContext commandContext, TaskEntity task) {
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        if (IdentityLinkType.ASSIGNEE.equals(type)) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass an explicit type constant such as IdentityLinkType.CANDIDATE or ASSIGNEE.
  2. Validate/normalize user-provided type values before calling the API.

Example fix

// before
taskService.deleteTaskIdentityLink(taskId, userId, groupId, null);
// after
taskService.deleteTaskIdentityLink(taskId, userId, groupId, IdentityLinkType.CANDIDATE);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(type, "identity link type is required");

Type guard

boolean validType(String type) { return type != null && Set.of(IdentityLinkType.ASSIGNEE, IdentityLinkType.OWNER, IdentityLinkType.CANDIDATE).contains(type); }

Try / catch

try { taskService.deleteTaskIdentityLink(taskId, userId, groupId, type); } catch (FlowableIllegalArgumentException e) { log.error("Missing link type: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling taskService.deleteUserIdentityLink/deleteGroupIdentityLink without supplying a link type, or passing a null type variable through generic identity-link code.

Common situations: Building delete calls dynamically where the type string is parsed from config/request input that was omitted; confusing deleteUserIdentityLink's implicit type handling with deleteTaskIdentityLink which requires an explicit type.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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