flowable/flowable-engine · error · FlowableIllegalArgumentException

Only one value of user or group is supported.

Error message

Only one value of user or group is supported.

What it means

When both the user and group fields of the identity link body are non-null but empty strings, FlowableIllegalArgumentException("Only one value of user or group is supported.") is thrown. A case instance identity link must specify exactly one identity value: a user or a group, not both (and not two empty values).

Source

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

            notes = "Note that the groupId in Response Body will always be null, as it’s only possible to involve users with a case instance.",
        code = 201)
    @ApiResponses(value = {
            @ApiResponse(code = 201, message = "Indicates the case instance was found and the link is created."),
            @ApiResponse(code = 400, message = "Indicates the requested body did not contain a userId or a type."),
            @ApiResponse(code = 404, message = "Indicates the requested case instance was not found.")
    })
    @PostMapping(value = "/cmmn-runtime/case-instances/{caseInstanceId}/identitylinks", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public RestIdentityLink createIdentityLink(@ApiParam(name = "caseInstanceId") @PathVariable String caseInstanceId, @RequestBody RestIdentityLink identityLink) {

        CaseInstance caseInstance = getCaseInstanceFromRequestWithoutAccessCheck(caseInstanceId);

        if (identityLink.getGroup() == null && identityLink.getUser() == null) {
            throw new FlowableIllegalArgumentException("User or group are required.");
        }
        
        if (StringUtils.isEmpty(identityLink.getGroup()) && StringUtils.isEmpty(identityLink.getUser())) {
            throw new FlowableIllegalArgumentException("Only one value of user or group is supported.");
        }

        if (identityLink.getType() == null) {
            throw new FlowableIllegalArgumentException("The identity link type is required.");
        }

        if (restApiInterceptor != null) {
            restApiInterceptor.createCaseInstanceIdentityLink(caseInstance, identityLink);
        }

        if (StringUtils.isNotEmpty(identityLink.getGroup())) {
            runtimeService.addGroupIdentityLink(caseInstance.getId(), identityLink.getGroup(), identityLink.getType());
            
        } else {
            runtimeService.addUserIdentityLink(caseInstance.getId(), identityLink.getUser(), identityLink.getType());
        }

        return restResponseFactory.createRestIdentityLink(identityLink.getType(), identityLink.getUser(), identityLink.getGroup(), null, null, caseInstance.getId());

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Provide exactly one of "user" or "group" with a non-empty value and omit the other.
  2. Convert empty strings to null/omit them in client serialization.
  3. Validate that at least one of user/group is a non-empty string before the call.

Example fix

// before
{"user": "", "group": "", "type": "participant"}
// after
{"user": "kermit", "type": "participant"}
Defensive patterns

Strategy: validation

Validate before calling

// Java
boolean hasUser = StringUtils.isNotEmpty(link.getUser());
boolean hasGroup = StringUtils.isNotEmpty(link.getGroup());
if (hasUser == hasGroup) {
    throw new IllegalArgumentException("exactly one of user or group must be non-empty");
}

Prevention

When it happens

Trigger: POST /cmmn-runtime/case-instances/{id}/identitylinks with a body where both "user" and "group" are present as empty strings (e.g. {"user":"","group":"","type":"participant"}) — passes the null check but fails the isEmpty check.

Common situations: Forms submitting empty inputs for both fields; generic serializers emitting empty strings instead of omitting fields; clients copying a payload template without clearing the unused field.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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