flowable/flowable-engine · error · FlowableException
CaseMigrationService cannot be null, Obtain your builder…
Error message
CaseMigrationService cannot be null, Obtain your builder instance from the CaseMigrationService to access this feature
What it means
CaseInstanceMigrationBuilderImpl methods that perform or validate migration require a CmmnMigrationService reference. If the builder was not created through CaseMigrationService.createCaseInstanceMigrationBuilder(), the reference is null and this FlowableException is thrown lazily when migrate/validate methods are called.
Solutions
- Create the builder via the service: cmmnEngine.getCmmnMigrationService().createCaseInstanceMigrationBuilder() (or CaseMigrationService entry point) instead of new CaseInstanceMigrationBuilderImpl()
- Inject/set the CmmnMigrationService on the builder instance if you must construct it manually
- Check you are using the migration service from the same CmmnEngine that owns the case instances
Example fix
// before CaseInstanceMigrationBuilderImpl builder = new CaseInstanceMigrationBuilderImpl(); builder.migrate(); // throws // after CaseInstanceMigrationBuilder builder = cmmnEngine.getCmmnMigrationService().createCaseInstanceMigrationBuilder(); builder.migrate();
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof builder.getCmmnMigrationService === 'undefined' || builder instanceof CaseInstanceMigrationBuilderImpl === false) {
builder = cmmnEngine.getCmmnMigrationService().createCaseInstanceMigrationBuilder();
} Type guard
function isServiceBackedBuilder(b) { return b != null && typeof b.migrate === 'function' && b.__createdByMigrationService === true; } Try / catch
try { builder.migrate(); } catch (e) { if (String(e.message).includes('CaseMigrationService cannot be null')) { builder = migrationService.createCaseInstanceMigrationBuilder(); return builder.migrate(); } throw e; } Prevention
- Never instantiate CaseInstanceMigrationBuilderImpl directly; always use CaseMigrationService.createCaseInstanceMigrationBuilder()
- Wrap builder creation in a factory helper in your codebase
- Ensure DI wiring provides the CmmnMigrationService to any manually created builders
When it happens
Trigger: Calling migrate(), validateMigration(), migrateCaseInstances(), batchMigrateCaseInstances() or validateMigrationOfCaseInstances() on a CaseInstanceMigrationBuilderImpl whose cmmnMigrationService field is null — i.e. the builder was constructed directly (new CaseInstanceMigrationBuilderImpl()) or deserialized rather than obtained from CaseMigrationService.
Common situations: Instantiating the builder implementation class directly in unit tests or DI setups; obtaining the builder from a different engine's migration service or after engine re-initialization; copying code that used the public API and swapping in the impl class.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Cannot find the case definition to migrate to, identified by
- Cannot find the case to migrate, with id
- Cannot find the historic case instance to migrate, with id
- Cannot migrate case(es), not enough information
- Case instance id is required
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/69785254b3c957c7.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationBuilderImpl.java:223
@Override
public void migrateCaseInstances(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId) {
getCmmnMigrationService().migrateCaseInstancesOfCaseDefinition(caseDefinitionKey, caseDefinitionVersion, caseDefinitionTenantId, getCaseInstanceMigrationDocument());
}
@Override
public Batch batchMigrateCaseInstances(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId) {
return getCmmnMigrationService().batchMigrateCaseInstancesOfCaseDefinition(caseDefinitionKey, caseDefinitionVersion, caseDefinitionTenantId, getCaseInstanceMigrationDocument());
}
@Override
public CaseInstanceMigrationValidationResult validateMigrationOfCaseInstances(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId) {
return getCmmnMigrationService().validateMigrationForCaseInstancesOfCaseDefinition(caseDefinitionKey, caseDefinitionVersion, caseDefinitionTenantId, getCaseInstanceMigrationDocument());
}
protected CmmnMigrationService getCmmnMigrationService() {
if (cmmnMigrationService == null) {
throw new FlowableException("CaseMigrationService cannot be null, Obtain your builder instance from the CaseMigrationService to access this feature");
}
return cmmnMigrationService;
}
}
View on GitHub (pinned to d6d39ce1c6)