flowable/flowable-engine · error · FlowableIllegalArgumentException

model is null

Error message

model is null

What it means

SaveModelCmd.execute validates the Model argument before persistence. Flowable throws FlowableIllegalArgumentException('model is null') when a null Model is passed to save, since the subsequent id check and manager call would NPE. It is a defensive argument-validation guard.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SaveModelCmd.java:39

import org.flowable.engine.impl.persistence.entity.ModelEntity;
import org.flowable.engine.impl.util.CommandContextUtil;

/**
 * @author Tijs Rademakers
 */
public class SaveModelCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;
    protected ModelEntity model;

    public SaveModelCmd(ModelEntity model) {
        this.model = model;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (model == null) {
            throw new FlowableIllegalArgumentException("model is null");
        }
        
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        if (model.getId() == null) {
            processEngineConfiguration.getModelEntityManager().insert(model);
        } else {
            processEngineConfiguration.getModelEntityManager().updateModel(model);
        }
        return null;
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure a non-null Model (e.g. repositoryService.newModel()) is created or fetched before saving.
  2. Guard the producer of the model object against null returns.
  3. When editing an existing model, fetch it by id and check for null before mutating and saving.

Example fix

// before
Model model = repositoryService.getModel(modelId);
model.setName("new name");
repositoryService.saveModel(model);
// after
Model model = repositoryService.getModel(modelId);
if (model == null) {
    model = repositoryService.newModel();
    model.setKey("my-model");
}
model.setName("new name");
repositoryService.saveModel(model);
Defensive patterns

Strategy: validation

Validate before calling

if (model == null) { throw new IllegalArgumentException("model must be non-null before saveModel"); }

Type guard

if (model instanceof Model && model != null) { /* safe to save */ }

Try / catch

try {
    repositoryService.saveModel(model);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("model is null")) {
        model = repositoryService.newModel();
        repositoryService.saveModel(model);
    }
}

Prevention

When it happens

Trigger: Calling RepositoryService.saveModel(null) or executing SaveModelCmd with a null model reference.

Common situations: Model lookup helper returning null (model deleted by id) and result passed straight to saveModel; JSON-to-model deserialization returning null; chaining methods where an earlier engine call returned no model.

Related errors


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