flowable/flowable-engine · error · FlowableIllegalArgumentException

Id cannot be null.

Error message

Id cannot be null.

What it means

FlowableIllegalArgumentException thrown by POST /flowable-idm-service/users when the request body has no 'id' field. The user id is the primary key of the identity model in Flowable, so a user cannot be created without it; the API rejects the request as a 400 bad request.

Solutions

  1. Include a non-null 'id' in the UserRequest JSON body before POSTing
  2. Generate the id client-side (e.g. username or UUID) before the create call
  3. Validate the request payload on the client and fail fast when id is absent
  4. If the intent was to update, use PUT /users/{userId} instead

Example fix

// before
{"firstName":"John","lastName":"Doe","email":"j@d.com"}
// after
{"id":"jdoe","firstName":"John","lastName":"Doe","email":"j@d.com"}
Defensive patterns

Strategy: validation

Validate before calling

// client-side guard before POST /users
function assertCreatable(u) {
  if (typeof u.id !== 'string' || u.id.length === 0) {
    throw new Error('UserRequest.id is required');
  }
}

Type guard

function hasId(u) { return u !== null && typeof u === 'object' && typeof u.id === 'string' && u.id.length > 0; }

Prevention

When it happens

Trigger: POST /users with a JSON body like {"firstName":"..."} missing 'id', or with 'id': null — typical when the client generates the id after the call or omits it for 'auto-generated' assumptions.

Common situations: Frontend forms that only collect email/name; clients migrating from systems that auto-generate user ids; serialization drops empty fields so id is silently removed from the payload.

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

Appendix: source

Thrown at modules/flowable-idm-rest/src/main/java/org/flowable/idm/rest/service/api/user/UserCollectionResource.java:149

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

        return paginateList(allRequestParams, query, "id", properties, idmRestResponseFactory::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 = "/users", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public UserResponse createUser(@RequestBody UserRequest userRequest) {
        if (userRequest.getId() == null) {
            throw new FlowableIllegalArgumentException("Id cannot be null.");
        }

        // 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());
        
        if (restApiInterceptor != null) {
            restApiInterceptor.createNewUser(created);
        }
        

View on GitHub (pinned to d6d39ce1c6)