flowable/flowable-engine · error · FlowableIllegalArgumentException

User or group are required.

Error message

User or group are required.

What it means

To create an identity link on a running process instance, the request body must reference either a user or a group. If both the user and group fields are null, createIdentityLink throws FlowableIllegalArgumentException('User or group are required.') because there is nothing to link.

Solutions

  1. Set either "user" or "group" in the request body, e.g. {"type":"participant","user":"kermit"}.
  2. Fix field-name typos so your client maps the user/group values to the correct JSON keys.
  3. Validate before sending: fail fast if both identityLink.user and identityLink.group are absent.

Example fix

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

Strategy: validation

Validate before calling

if (link.getUser() == null && link.getGroup() == null) {
    throw new IllegalArgumentException("Identity link body must set 'user' or 'group'");
}

Try / catch

try {
    restClient.createIdentityLink(instanceId, link);
} catch (HttpClientErrorException.BadRequest e) {
    if (e.getResponseBodyAsString().contains("User or group are required")) {
        // correct payload mapping
    }
}

Prevention

When it happens

Trigger: POST /runtime/process-instances/{processInstanceId}/identitylinks with a body like {"type":"participant"} — no "user" and no "group" set. Thrown at ProcessInstanceIdentityLinkCollectionResource.java:76.

Common situations: Building the RestIdentityLink body but forgetting to set either field; JSON keys misspelled (e.g. "username" instead of "user"); serializers dropping empty strings/names so both fields arrive 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/73868f5bde75406c. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceIdentityLinkCollectionResource.java:76

        return restResponseFactory.createRestIdentityLinks(runtimeService.getIdentityLinksForProcessInstance(processInstance.getId()));
    }

    @ApiOperation(value = "Add an involved user to a process instance", tags = {"Process Instance Identity Links" }, nickname = "createProcessInstanceIdentityLinks",
            notes = "Note that the groupId in Response Body will always be null, as it’s only possible to involve users with a process-instance.",
            code = 201)
    @ApiResponses(value = {
            @ApiResponse(code = 201, message = "Indicates the process 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 process instance was not found.")
    })
    @PostMapping(value = "/runtime/process-instances/{processInstanceId}/identitylinks", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public RestIdentityLink createIdentityLink(@ApiParam(name = "processInstanceId") @PathVariable String processInstanceId, @RequestBody RestIdentityLink identityLink) {

        ProcessInstance processInstance = getProcessInstanceFromRequestWithoutAccessCheck(processInstanceId);

        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.createProcessInstanceIdentityLink(processInstance, identityLink);
        }

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

View on GitHub (pinned to d6d39ce1c6)