flowable/flowable-engine · error · FlowableIllegalArgumentException

IdentityId is required.

Error message

IdentityId is required.

What it means

Deleting or fetching a single identity link requires the identityId path variable (the user or group name). If it is absent or null, validateIdentityLinkArguments throws FlowableIllegalArgumentException because a link cannot be uniquely addressed without it.

Solutions

  1. Provide the actual user or group id in the URL path
  2. Check that the variable holding the identity name is non-null/non-empty before building the URL
  3. Fail fast in client code when the principal name is unknown instead of issuing the call

Example fix

// before
String url = "/cmmn-runtime/tasks/123/identitylinks/users/" + userId + "/candidate"; // userId == null
// after
Objects.requireNonNull(userId, "userId required for identity link lookup");
String url = "/cmmn-runtime/tasks/123/identitylinks/users/" + userId + "/candidate";
Defensive patterns

Strategy: validation

Validate before calling

function canAddressIdentityLink(family, identityId, type) {
  return !!identityId && !!type && ['users','groups'].includes(family);
}

Type guard

function hasIdentityId(a) {
  return typeof a.identityId === 'string' && a.identityId.length > 0;
}

Try / catch

try {
  await del(url);
} catch (e) {
  if (e.status === 400 && /IdentityId is required/.test(e.body.message)) {
    throw new Error('identityId path variable missing');
  }
  throw e;
}

Prevention

When it happens

Trigger: GET/DELETE /cmmn-runtime/tasks/{taskId}/identitylinks/{family}/{identityId}/{type} with an empty or missing {identityId} segment.

Common situations: A user/group name that was never populated in the calling code; empty string from a config field; URL templating that drops empty path variables.

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/891500c2616b87dc. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskIdentityLinkResource.java:100

        IdentityLink link = getIdentityLink(family, identityId, type, task.getId());

        if (restApiInterceptor != null) {
            restApiInterceptor.deleteTaskIdentityLink(task, link);
        }

        if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family)) {
            taskService.deleteUserIdentityLink(task.getId(), identityId, type);
        } else {
            taskService.deleteGroupIdentityLink(task.getId(), identityId, type);
        }
    }

    protected void validateIdentityLinkArguments(String family, String identityId, String type) {
        if (family == null || (!CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family))) {
            throw new FlowableIllegalArgumentException("Identity link family should be 'users' or 'groups'.");
        }
        if (identityId == null) {
            throw new FlowableIllegalArgumentException("IdentityId is required.");
        }
        if (type == null) {
            throw new FlowableIllegalArgumentException("Type is required.");
        }
    }

    protected IdentityLink getIdentityLink(String family, String identityId, String type, String taskId) {
        boolean isUser = family.equals(CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS);

        // Perhaps it would be better to offer getting a single identitylink
        // from the API
        List<IdentityLink> allLinks = taskService.getIdentityLinksForTask(taskId);
        for (IdentityLink link : allLinks) {
            boolean rightIdentity = false;
            if (isUser) {
                rightIdentity = identityId.equals(link.getUserId());
            } else {
                rightIdentity = identityId.equals(link.getGroupId());

View on GitHub (pinned to d6d39ce1c6)