flowable/flowable-engine · error · FlowableIllegalArgumentException

user is null

Error message

user is null

What it means

SaveUserCmd persists a User through the UserEntityManager; for new users it also hashes the password with the configured PasswordEncoder and salt. A null User cannot be inserted or updated, so the command throws FlowableIllegalArgumentException immediately.

Source

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

 * @author Joram Barrez
 */
public class SaveUserCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;
    
    protected IdmEngineConfiguration idmEngineConfiguration;
    
    protected User user;

    public SaveUserCmd(User user, IdmEngineConfiguration idmEngineConfiguration) {
        this.user = user;
        this.idmEngineConfiguration = idmEngineConfiguration;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (user == null) {
            throw new FlowableIllegalArgumentException("user is null");
        }
        
        if (idmEngineConfiguration.getUserEntityManager().isNewUser(user)) {
            if (user.getPassword() != null) {
                PasswordEncoder passwordEncoder = idmEngineConfiguration.getPasswordEncoder();
                PasswordSalt passwordSalt = idmEngineConfiguration.getPasswordSalt();
                user.setPassword(passwordEncoder.encode(user.getPassword(), passwordSalt));
            }
            
            if (user instanceof UserEntity) {
                idmEngineConfiguration.getUserEntityManager().insert((UserEntity) user, true);
            } else {
                CommandContextUtil.getDbSqlSession(commandContext).insert((Entity) user, idmEngineConfiguration.getIdGenerator());
            }
        } else {
            UserEntity dbUser = idmEngineConfiguration.getUserEntityManager().findById(user.getId());
            user.setPassword(dbUser.getPassword());
            idmEngineConfiguration.getUserEntityManager().updateUser(user);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Create the user first (identityService.newUser(id)) and set fields before saving
  2. Verify the preceding lookup that returned the null user reference
  3. Null-check before save; create or skip depending on business logic
  4. Validate request/config payloads so the User object is always populated

Example fix

// before
identityService.saveUser(user);
// after
if (user == null) {
    user = identityService.newUser(userId);
    user.setPassword(rawPassword);
}
identityService.saveUser(user);
Defensive patterns

Strategy: validation

Validate before calling

if (user == null) throw new IllegalArgumentException("user must not be null");

Type guard

boolean isSavableUser(User u) { return u != null && u.getId() != null && !u.getId().trim().isEmpty(); }

Try / catch

try { identityService.saveUser(user); } catch (FlowableIllegalArgumentException e) { log.error("Attempted to save null user", e); }

Prevention

When it happens

Trigger: Calling identityService.saveUser(null) or executing new SaveUserCmd(config, null); also when the user reference comes from a failed lookup or an unbound process/task variable.

Common situations: Chain like saveUser(query().userId(id).singleResult()) when the user no longer exists; user objects built from unvalidated request bodies where the field is absent.

Related errors


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