{"record":{"id":"be831f1dedb9e2ea","repo":"flowable/flowable-engine","slug":"casemigrationservice-cannot-be-null-obtain-your-b-be831f","errorCode":null,"errorMessage":"CaseMigrationService cannot be null, Obtain your builder instance from the CaseMigrationService to access this feature","messagePattern":"CaseMigrationService cannot be null, Obtain your builder instance from the CaseMigrationService to access this feature","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/HistoricCaseInstanceMigrationBuilderImpl.java","lineNumber":96,"sourceCode":"\n    @Override\n    public Batch batchMigrateHistoricCaseInstances(String caseDefinitionId) {\n        return getCmmnMigrationService().batchMigrateHistoricCaseInstancesOfCaseDefinition(caseDefinitionId, getHistoricCaseInstanceMigrationDocument());\n    }\n\n    @Override\n    public void migrateHistoricCaseInstances(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId) {\n        getCmmnMigrationService().migrateHistoricCaseInstancesOfCaseDefinition(caseDefinitionKey, caseDefinitionVersion, caseDefinitionTenantId, getHistoricCaseInstanceMigrationDocument());\n    }\n\n    @Override\n    public Batch batchMigrateHistoricCaseInstances(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId) {\n        return getCmmnMigrationService().batchMigrateHistoricCaseInstancesOfCaseDefinition(caseDefinitionKey, caseDefinitionVersion, caseDefinitionTenantId, getHistoricCaseInstanceMigrationDocument());\n    }\n\n    protected CmmnMigrationService getCmmnMigrationService() {\n        if (cmmnMigrationService == null) {\n            throw new FlowableException(\"CaseMigrationService cannot be null, Obtain your builder instance from the CaseMigrationService to access this feature\");\n        }\n        return cmmnMigrationService;\n    }\n\n}\n","sourceCodeStart":78,"sourceCodeEnd":102,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/HistoricCaseInstanceMigrationBuilderImpl.java#L78-L102","documentation":"HistoricCaseInstanceMigrationBuilderImpl relies on a reference to the CaseMigrationService that created it. If the builder was constructed directly (not via CaseMigrationService.createHistoricCaseInstanceMigrationBuilder()), that reference is null and any migrate/batch operation fails with this FlowableException.","triggerScenarios":"Instantiating HistoricCaseInstanceMigrationBuilderImpl with new (or via a non-standard factory) and then calling migrate(), migrateHistoricCaseInstances(...) or batchMigrateHistoricCaseInstances(...) without ever setting cmmnMigrationService.","commonSituations":"Manual bean construction/DI wiring that skips the service factory; copying builder creation code without injecting the migration service; unit tests constructing the builder directly.","solutions":["Obtain the builder via cmmnEngineConfiguration.getCaseMigrationService().createHistoricCaseInstanceMigrationBuilder() (or the CmmnEngine/public API equivalent).","Inject/set the CmmnMigrationService into the builder if you must construct it manually.","Refactor to use the CmmnRuntimeService/CmmnManagementService migration API entry points instead of instantiating internal classes."],"exampleFix":"// before\nHistoricCaseInstanceMigrationBuilderImpl b = new HistoricCaseInstanceMigrationBuilderImpl();\nb.migrateToCaseDefinition(\"orderCase\").migrate();\n// after\nHistoricCaseInstanceMigrationBuilder b = cmmnEngineConfiguration.getCaseMigrationService()\n    .createHistoricCaseInstanceMigrationBuilder();\nb.migrateToCaseDefinition(\"orderCase\").migrate();","handlingStrategy":"type-guard","validationCode":"if (builder == null || ((HistoricCaseInstanceMigrationBuilderImpl) builder).getCmmnMigrationServiceForTest() == null) {\n    throw new IllegalStateException(\"Builder must be created via CaseMigrationService\");\n}","typeGuard":"if (migrationService == null) throw new IllegalStateException(\"Create the builder via CaseMigrationService.createHistoricCaseInstanceMigrationBuilder()\");","tryCatchPattern":"try { builder.migrate(); } catch (FlowableException e) { if (e.getMessage().contains(\"CaseMigrationService cannot be null\")) { /* rebuild via service factory */ } throw e; }","preventionTips":["Never instantiate migration builders with new; always use CaseMigrationService factory methods.","In Spring configs, expose CaseMigrationService as a bean and inject it.","Add constructor guards in wrappers around internal engine classes.","Prefer the public CmmnRuntimeService/ManagementService migration APIs."],"tags":["cmmn","migration","builder","api-misuse"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}