flowable/flowable-engine · error · FlowableIllegalArgumentException

Id cannot be null.

Error message

Id cannot be null.

What it means

UserCollectionResource.createUser validates that UserRequest.id is non-null before creating the user, throwing FlowableIllegalArgumentException (HTTP 400). Flowable users require a caller-supplied unique id, which becomes the primary identifier in ACT_ID_USER.

Solutions

  1. Include a non-null "id" in the POST /identity/users body (optionally equal to the username).
  2. Map the client's username field to the "id" JSON property.
  3. Validate required fields client-side before sending.

Example fix

// before
POST /identity/users {"firstName":"John","lastName":"Doe","email":"jdoe@example.com"}
// after
POST /identity/users {"id":"jdoe","firstName":"John","lastName":"Doe","email":"jdoe@example.com"}
Defensive patterns

Strategy: validation

Validate before calling

if (userRequest == null || userRequest.getId() == null || userRequest.getId().isBlank()) {
    throw new IllegalArgumentException("User id is required before POST /identity/users");
}

Type guard

boolean hasId(UserRequest r) { return r != null && r.getId() != null && !r.getId().isEmpty(); }

Prevention

When it happens

Trigger: POST /identity/users with a JSON body missing the "id" field, e.g. {"firstName":"John","lastName":"Doe","email":"jdoe@example.com"}.

Common situations: Assuming the server auto-generates ids from the email; DTO field name mismatch (username vs id) yielding null after Jackson binding; script building the payload conditionally and skipping the id.

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/a73a6893318ceff5. Report an issue: GitHub.

Appendix: source

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

        
        if (restApiInterceptor != null) {
            restApiInterceptor.accessUserInfoWithQuery(query);
        }

        return paginateList(allRequestParams, query, "id", properties, restResponseFactory::createUserResponseList);
    }

    @ApiOperation(value = "Create a user", tags = { "Users" }, code = 201)
    @ApiResponses(value = {
            @ApiResponse(code = 201, message = "Indicates the user was created."),
            @ApiResponse(code = 400, message = "Indicates the id of the user was missing.")

    })
    @PostMapping(value = "/identity/users", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public UserResponse createUser(@RequestBody UserRequest userRequest) {
        if (userRequest.getId() == null) {
            throw new FlowableIllegalArgumentException("Id cannot be null.");
        }
        
        if (restApiInterceptor != null) {
            restApiInterceptor.createUser(userRequest);
        }

        // Check if a user with the given ID already exists so we return a CONFLICT
        if (identityService.createUserQuery().userId(userRequest.getId()).count() > 0) {
            throw new FlowableConflictException("A user with id '" + userRequest.getId() + "' already exists.");
        }

        User created = identityService.newUser(userRequest.getId());
        created.setEmail(userRequest.getEmail());
        created.setFirstName(userRequest.getFirstName());
        created.setLastName(userRequest.getLastName());
        created.setDisplayName(userRequest.getDisplayName());
        created.setPassword(userRequest.getPassword());
        created.setTenantId(userRequest.getTenantId());

View on GitHub (pinned to d6d39ce1c6)