flowable/flowable-engine · error · FlowableIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

AddIdentityLinkCmd.validateParams rejects a null taskId because an identity link (user/group association) can only be attached to an existing task. It throws FlowableIllegalArgumentException before any entity lookup or persistence happens.

Source

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

    protected String identityId;

    protected int identityIdType;

    protected String identityType;

    public AddIdentityLinkCmd(String taskId, String identityId, int identityIdType, String identityType) {
        super(taskId);
        validateParams(taskId, identityId, identityIdType, identityType);
        this.taskId = taskId;
        this.identityId = identityId;
        this.identityIdType = identityIdType;
        this.identityType = identityType;
    }

    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

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the task exists and capture its id before adding an identity link
  2. Null-check taskId at the caller and fail with a clear client-facing message
  3. Use taskService.createTaskQuery().taskId(id) to verify existence, then use task.getId()

Example fix

// before
taskService.addUserIdentityLink(taskId, userId, IdentityLinkType.PARTICIPANT);
// after
if (taskId == null) throw new IllegalArgumentException("taskId is required");
taskService.addUserIdentityLink(taskId, userId, IdentityLinkType.PARTICIPANT);
Defensive patterns

Strategy: validation

Validate before calling

if (taskId == null || taskId.isBlank()) throw new IllegalArgumentException("taskId is required");
taskService.addUserIdentityLink(taskId, userId, IdentityLinkType.PARTICIPANT);

Type guard

boolean hasTaskId(String taskId) { return taskId != null && !taskId.isBlank(); }

Try / catch

try {
    taskService.addUserIdentityLink(taskId, userId, type);
} catch (FlowableIllegalArgumentException e) {
    throw new BadRequestException(e.getMessage());
}

Prevention

When it happens

Trigger: Calling cmmnTaskService.addUserIdentityLink(null, userId, type), addGroupIdentityLink(null, ...), or new AddIdentityLinkCmd(null, ...) where the taskId parameter was never set (e.g. null from an upstream map/request param).

Common situations: REST/DTO layer passing through an unset taskId, a variable holding the task id being null after a failed task query, or wiring the wrong variable into the service call.

Related errors


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