flowable/flowable-engine · error · FlowableIllegalArgumentException

Type is required.

Error message

Type is required.

What it means

Guard in CaseInstanceIdentityLinkResource.validateIdentityLinkArguments: family and identityId passed their checks but the identity link type is null; deleting or creating an identity link requires the link type (assignee, candidate, ...).

Solutions

  1. Include the identity link type in the URL, e.g. 'participant'.
  2. Validate the type is non-null before the call.
  3. Use the same type string that was used when the identity link was created.

Example fix

// before
DELETE /cmmn-runtime/case-instances/case-1/identitylinks/users/kermit
// after
DELETE /cmmn-runtime/case-instances/case-1/identitylinks/users/kermit/participant
Defensive patterns

Strategy: validation

Validate before calling

// Java
if (type == null || type.isEmpty()) {
    throw new IllegalArgumentException("identity link type path segment is required");
}

Prevention

When it happens

Trigger: GET or DELETE .../identitylinks/{family}/{identityId}/{type} with the {type} segment missing or not supplied by the caller.

Common situations: Omitting the type segment assuming it is optional; URL templates with unfilled placeholders; client methods with defaults that pass null.

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

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceIdentityLinkResource.java:108

        }

        if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family)) {
            runtimeService.deleteGroupIdentityLink(caseInstance.getId(), identityId, type);
            
        } else {
            runtimeService.deleteUserIdentityLink(caseInstance.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 identityId, String family, String type, String caseInstanceId) {
        // Perhaps it would be better to offer getting a single identity link
        // from the API
        List<IdentityLink> allLinks = runtimeService.getIdentityLinksForCaseInstance(caseInstanceId);
        for (IdentityLink link : allLinks) {
            if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family) && identityId.equals(link.getUserId()) && link.getType().equals(type)) {
                return link;
            
            } else if (CmmnRestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && identityId.equals(link.getGroupId()) && link.getType().equals(type)) {
                return link;
            }
        }
        throw new FlowableObjectNotFoundException("Could not find the requested identity link.", IdentityLink.class);
    }
}

View on GitHub (pinned to d6d39ce1c6)