{"record":{"id":"cd590c0bb386985e","repo":"flowable/flowable-engine","slug":"model-is-null","errorCode":null,"errorMessage":"model is null","messagePattern":"model is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SaveModelCmd.java","lineNumber":39,"sourceCode":"import org.flowable.engine.impl.persistence.entity.ModelEntity;\nimport org.flowable.engine.impl.util.CommandContextUtil;\n\n/**\n * @author Tijs Rademakers\n */\npublic class SaveModelCmd implements Command<Void>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    protected ModelEntity model;\n\n    public SaveModelCmd(ModelEntity model) {\n        this.model = model;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        if (model == null) {\n            throw new FlowableIllegalArgumentException(\"model is null\");\n        }\n        \n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        if (model.getId() == null) {\n            processEngineConfiguration.getModelEntityManager().insert(model);\n        } else {\n            processEngineConfiguration.getModelEntityManager().updateModel(model);\n        }\n        return null;\n    }\n\n}\n","sourceCodeStart":21,"sourceCodeEnd":52,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SaveModelCmd.java#L21-L52","documentation":"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.","triggerScenarios":"Calling RepositoryService.saveModel(null) or executing SaveModelCmd with a null model reference.","commonSituations":"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.","solutions":["Ensure a non-null Model (e.g. repositoryService.newModel()) is created or fetched before saving.","Guard the producer of the model object against null returns.","When editing an existing model, fetch it by id and check for null before mutating and saving."],"exampleFix":"// before\nModel model = repositoryService.getModel(modelId);\nmodel.setName(\"new name\");\nrepositoryService.saveModel(model);\n// after\nModel model = repositoryService.getModel(modelId);\nif (model == null) {\n    model = repositoryService.newModel();\n    model.setKey(\"my-model\");\n}\nmodel.setName(\"new name\");\nrepositoryService.saveModel(model);","handlingStrategy":"validation","validationCode":"if (model == null) { throw new IllegalArgumentException(\"model must be non-null before saveModel\"); }","typeGuard":"if (model instanceof Model && model != null) { /* safe to save */ }","tryCatchPattern":"try {\n    repositoryService.saveModel(model);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"model is null\")) {\n        model = repositoryService.newModel();\n        repositoryService.saveModel(model);\n    }\n}","preventionTips":["Null-check the result of getModel(id) before mutating/saving","Use repositoryService.newModel() to create models","Avoid chaining calls whose earlier step can return null"],"tags":["validation","null-check","model","illegal-argument"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}