flowable/flowable-engine · error · FlowableIllegalArgumentException

The value cannot be null.

Error message

The value cannot be null.

What it means

FlowableIllegalArgumentException thrown by the REST endpoint PUT /identity/users/{userId}/info/{key} when the JSON request body has no 'value' field (or it is JSON null). The library requires a non-null value before it will store a user info entry via IdentityService.setUserInfo. It is a client-side request validation error, not an internal fault.

Solutions

  1. Include a non-null "value" field in the JSON body, e.g. {"value":"jdoe@example.com"}.
  2. Verify the request Content-Type is application/json and the field is named exactly "value".
  3. If the intent is to remove the info entry, use the DELETE /identity/users/{userId}/info/{key} endpoint instead of PUT with a null value.
  4. Validate the body client-side before sending and return a 400 with a clear message.

Example fix

// before
PUT /flowable-rest/identity/users/jdoe/info/email
{}

// after
PUT /flowable-rest/identity/users/jdoe/info/email
{"value":"jdoe@example.com"}
Defensive patterns

Strategy: validation

Validate before calling

const body = { key: 'email', value: 'jdoe@example.com' };
if (body.value == null) {
  throw new Error('PUT user info requires a non-null "value" field');
}
await fetch(`/identity/users/${userId}/info/${body.key}`, {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(body)
});

Type guard

function hasValue(body) {
  return body != null && typeof body === 'object' && body.value !== undefined && body.value !== null;
}

Try / catch

try {
  const res = await fetch(url, opts);
  if (res.status === 400) {
    const msg = await res.text();
    if (msg.includes('The value cannot be null')) { /* fix body: add value */ }
  }
} catch (e) { /* network error, not this case */ }

Prevention

When it happens

Trigger: Calling setUserInfo (PUT identity/users/{userId}/info/{key}) with a body like {} or {"key":"k"} where userRequest.getValue() == null. Also triggered by sending the wrong JSON field name (e.g. "val" instead of "value") so the deserialized value stays null.

Common situations: Typo'd or missing 'value' property in the request JSON; sending form-encoded data instead of JSON; Content-Type not application/json so the body fails to bind; scripting a bulk user-info import where some records have empty values.

Related errors


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

Appendix: source

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

        }

        return restResponseFactory.createUserInfoResponse(key, existingValue, user.getId());
    }

    @ApiOperation(value = "Update a user’s info", tags = { "Users" }, nickname = "updateUserInfo")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Indicates the user was found and the info has been updated."),
            @ApiResponse(code = 400, message = "Indicates the value was missing from the request body."),
            @ApiResponse(code = 404, message = "Indicates the requested user was not found or the user does not have info for the given key. Status description contains additional information about the error.")
    })
    @PutMapping(value = "/identity/users/{userId}/info/{key}", produces = "application/json")
    public UserInfoResponse setUserInfo(@ApiParam(name = "userId") @PathVariable("userId") String userId, @ApiParam(name = "key") @PathVariable("key") String key, @RequestBody UserInfoRequest userRequest) {

        User user = getUserFromRequest(userId);
        String validKey = getValidKeyFromRequest(user, key);

        if (userRequest.getValue() == null) {
            throw new FlowableIllegalArgumentException("The value cannot be null.");
        }

        if (userRequest.getKey() == null || validKey.equals(userRequest.getKey())) {
            identityService.setUserInfo(user.getId(), key, userRequest.getValue());
        } else {
            throw new FlowableIllegalArgumentException("Key provided in request body does not match the key in the resource URL.");
        }

        return restResponseFactory.createUserInfoResponse(key, userRequest.getValue(), user.getId());
    }

    @ApiOperation(value = "Delete a user’s info", tags = { "Users" }, code = 204)
    @ApiResponses(value = {
            @ApiResponse(code = 204, message = "Indicates the user was found and the info for the given key has been deleted. Response body is left empty intentionally."),
            @ApiResponse(code = 404, message = "Indicates the requested user was not found or the user does not have info for the given key. Status description contains additional information about the error.")
    })
    @DeleteMapping("/identity/users/{userId}/info/{key}")
    @ResponseStatus(HttpStatus.NO_CONTENT)

View on GitHub (pinned to d6d39ce1c6)