flowable/flowable-engine · error · FlowableIllegalArgumentException

groupId is null

Error message

groupId is null

What it means

DeleteMembershipCmd.execute() validates both membership key components; this error is raised when groupId is null (after the userId check passed). A membership cannot be located without both userId and groupId.

Solutions

  1. Pass a non-null groupId to IdentityService.deleteMembership().
  2. Resolve the group by name first and fail with a clear 'group not found' error if the lookup yields null.
  3. Validate both parameters at the service/UI boundary before calling the engine.
  4. Catch FlowableIllegalArgumentException and map it to a 400-style validation response.

Example fix

// before
identityService.deleteMembership(userId, groupId); // groupId may be null

// after
Objects.requireNonNull(groupId, "groupId is required to delete a membership");
identityService.deleteMembership(userId, groupId);
Defensive patterns

Strategy: validation

Validate before calling

if (groupId == null) {
    throw new IllegalArgumentException("groupId must be provided before deleting a membership");
}
if (userId == null) {
    throw new IllegalArgumentException("userId must be provided before deleting a membership");
}

Type guard

boolean hasValidMembershipKey(String userId, String groupId) {
    return userId != null && groupId != null;
}

Try / catch

try {
    identityService.deleteMembership(userId, groupId);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("groupId is null")) {
        throw new InvalidRequestException("groupId is required to delete a membership");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling IdentityService.deleteMembership(userId, null), or new DeleteMembershipCmd(userId, null); typically when the group id comes from a lookup that returned nothing or an unset form field.

Common situations: Removing a user from a group whose id was resolved by name and the name lookup failed; admin UI sending only userId; refactoring where parameter order was changed and groupId fell through as null.

Related errors


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

Appendix: source

Thrown at modules/flowable-idm-engine/src/main/java/org/flowable/idm/engine/impl/cmd/DeleteMembershipCmd.java:42

 */
public class DeleteMembershipCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;
    String userId;
    String groupId;

    public DeleteMembershipCmd(String userId, String groupId) {
        this.userId = userId;
        this.groupId = groupId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (userId == null) {
            throw new FlowableIllegalArgumentException("userId is null");
        }
        if (groupId == null) {
            throw new FlowableIllegalArgumentException("groupId is null");
        }

        CommandContextUtil.getMembershipEntityManager(commandContext).deleteMembership(userId, groupId);

        return null;
    }

}

View on GitHub (pinned to d6d39ce1c6)