flowable/flowable-engine · error · FlowableIllegalArgumentException

Only one of user or group can be used to create an identity…

Error message

Only one of user or group can be used to create an identity link.

What it means

Thrown when creating a process-definition identity link with BOTH a user and a group set. Flowable requires the link to target exactly one principal, so the request is rejected as an invalid argument.

Solutions

  1. Send only one of user or group per request; issue two requests if both are needed
  2. Clear the unused field client-side before serializing the JSON
  3. Add client-side validation that exactly one of user/group is populated

Example fix

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

Strategy: validation

Validate before calling

if (body.getGroup() != null && body.getUser() != null) throw new IllegalArgumentException("set only one of user or group");

Try / catch

try { createIdentityLink(defId, link); } catch (FlowableIllegalArgumentException e) { /* strip the extra field and resend */ }

Prevention

When it happens

Trigger: POST identity link with a body containing both fields, e.g. {"type":"candidate","user":"kermit","group":"sales"}.

Common situations: Client code copying a payload template and forgetting to clear the other field; UI forms submitting both inputs; bulk import scripts mapping both columns unconditionally.

Related errors


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

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/ProcessDefinitionIdentityLinkCollectionResource.java:79

            notes = "It is possible to add either a user or a group.",
            code = 201)
    @ApiResponses(value = {
            @ApiResponse(code = 201, message = "Indicates the process definition was found and the identity link was created."),
            @ApiResponse(code = 400, message = "Indicates the body does not contain the correct information."),
            @ApiResponse(code = 404, message = "Indicates the requested process definition was not found.")
    })
    @PostMapping(value = "/repository/process-definitions/{processDefinitionId}/identitylinks", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public RestIdentityLink createIdentityLink(@ApiParam(name = "processDefinitionId") @PathVariable String processDefinitionId, @RequestBody RestIdentityLink identityLink) {

        ProcessDefinition processDefinition = getProcessDefinitionFromRequestWithoutAccessCheck(processDefinitionId);

        if (identityLink.getGroup() == null && identityLink.getUser() == null) {
            throw new FlowableIllegalArgumentException("A group or a user is required to create an identity link.");
        }

        if (identityLink.getGroup() != null && identityLink.getUser() != null) {
            throw new FlowableIllegalArgumentException("Only one of user or group can be used to create an identity link.");
        }

        if (restApiInterceptor != null) {
            restApiInterceptor.createProcessDefinitionIdentityLink(processDefinition, identityLink);
        }

        if (identityLink.getGroup() != null) {
            repositoryService.addCandidateStarterGroup(processDefinition.getId(), identityLink.getGroup());
        } else {
            repositoryService.addCandidateStarterUser(processDefinition.getId(), identityLink.getUser());
        }

        // Always candidate for process-definition. User-provided value is
        // ignored
        identityLink.setType(IdentityLinkType.CANDIDATE);

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

View on GitHub (pinned to d6d39ce1c6)