flowable/flowable-engine · error · FlowableIllegalArgumentException
userId is null
Error message
userId is null
What it means
CreateUserCmd's constructor rejects a null userId immediately. The IDM engine requires a user identifier to create or operate on a User entity, so a null id is treated as a programming/API-usage error and fails fast via FlowableIllegalArgumentException before execute() runs.
Solutions
- Supply a non-null userId when constructing CreateUserCmd or when calling the IdentityService wrapper.
- Validate the id at the application boundary (e.g. require username in REST payload) before invoking the engine.
- If the id is derived from another system, skip or reject records with null ids instead of passing them to the engine.
- Wrap the call in a try-catch for FlowableIllegalArgumentException to convert it into a domain-level validation error.
Example fix
// before identityService.saveUser(identityService.newUser(userId)); // userId may be null // after Objects.requireNonNull(userId, "userId is required"); identityService.saveUser(identityService.newUser(userId));
Defensive patterns
Strategy: validation
Validate before calling
if (userId == null || userId.trim().isEmpty()) {
throw new IllegalArgumentException("userId must be a non-empty String before creating a user");
} Type guard
boolean hasValidUserId(String userId) {
return userId != null && !userId.trim().isEmpty();
} Try / catch
try {
identityService.saveUser(identityService.newUser(userId));
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("userId is null")) {
throw new InvalidRequestException("User id must not be null");
}
throw e;
} Prevention
- Enforce @NotNull/@NotBlank on user id DTOs at the REST layer.
- Reject records with missing ids during bulk provisioning before touching the engine.
- Use Objects.requireNonNull near the call site to fail with a descriptive message.
- Keep id derivation logic (SSO/LDAP mapping) covered by tests so nulls surface early.
When it happens
Trigger: Calling new CreateUserCmd(null), or calling IdentityService.newUser(null) / user-service endpoints that construct this command with a null user id.
Common situations: Username sourced from an HTTP request body, SSO claim, or LDAP attribute that is missing; batch user provisioning where some records lack ids; migration scripts mapping columns that are null for some rows.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0067b17de64e30e5.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-idm-engine/src/main/java/org/flowable/idm/engine/impl/cmd/CreateUserCmd.java:35
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.idm.api.User;
import org.flowable.idm.engine.impl.util.CommandContextUtil;
/**
* @author Tom Baeyens
*/
public class CreateUserCmd implements Command<User>, Serializable {
private static final long serialVersionUID = 1L;
protected String userId;
public CreateUserCmd(String userId) {
if (userId == null) {
throw new FlowableIllegalArgumentException("userId is null");
}
this.userId = userId;
}
@Override
public User execute(CommandContext commandContext) {
return CommandContextUtil.getUserEntityManager(commandContext).createNewUser(userId);
}
}
View on GitHub (pinned to d6d39ce1c6)