flowable/flowable-engine · error · FlowableIllegalArgumentException

UserId cannot be null.

Error message

UserId cannot be null.

What it means

GroupMembershipCollectionResource.createMembership validates MembershipRequest.userId before creating the membership. A null userId throws FlowableIllegalArgumentException (HTTP 400) because identityService.createMembership requires both a user id and a group id.

Solutions

  1. Include a non-null "userId" in the request body.
  2. Fix client serialization so the user identifier maps to the "userId" property.
  3. Validate the payload client-side before the POST.

Example fix

// before
POST /identity/groups/sales/members {"user":"jdoe"}
// after
POST /identity/groups/sales/members {"userId":"jdoe"}
Defensive patterns

Strategy: validation

Validate before calling

if (member == null || member.getUserId() == null || member.getUserId().isBlank()) {
    throw new IllegalArgumentException("userId is required for group membership");
}

Type guard

boolean hasUserId(MembershipRequest r) { return r != null && r.getUserId() != null && !r.getUserId().isEmpty(); }

Prevention

When it happens

Trigger: POST /identity/groups/{groupId}/members with a body missing "userId", e.g. {"userId":null} or {}.

Common situations: Client form field never filled in; JSON property name mismatch (memberId/user vs userId) so Jackson binds null; automated script building the payload from a variable that is 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/41a638a36c8763ce. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/identity/GroupMembershipCollectionResource.java:54

@RestController
@Api(tags = { "Groups" }, authorizations = { @Authorization(value = "basicAuth") })
public class GroupMembershipCollectionResource extends BaseGroupResource {

    @ApiOperation(value = "Add a member to a group", tags = { "Groups" }, code = 201)
    @ApiResponses(value = {
            @ApiResponse(code = 201, message = "Indicates the group was found and the member has been added."),
            @ApiResponse(code = 400, message = "Indicates the userId was not included in the request body."),
            @ApiResponse(code = 404, message = "Indicates the requested group was not found."),
            @ApiResponse(code = 409, message = "Indicates the requested user is already a member of the group.")
    })
    @PostMapping(value = "/identity/groups/{groupId}/members", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public MembershipResponse createMembership(@ApiParam(name = "groupId") @PathVariable String groupId, @RequestBody MembershipRequest memberShip) {

        Group group = getGroupFromRequest(groupId);

        if (memberShip.getUserId() == null) {
            throw new FlowableIllegalArgumentException("UserId cannot be null.");
        }

        // Check if user is member of group since API does not return typed exception
        if (identityService.createUserQuery().memberOfGroup(group.getId()).userId(memberShip.getUserId()).count() > 0) {
            throw new FlowableConflictException("User '" + memberShip.getUserId() + "' is already part of group '" + group.getId() + "'.");
        }

        identityService.createMembership(memberShip.getUserId(), group.getId());

        return restResponseFactory.createMembershipResponse(memberShip.getUserId(), group.getId());
    }
}

View on GitHub (pinned to d6d39ce1c6)