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

  1. Create the builder via the service: cmmnEngine.getCmmnMigrationService().createCaseInstanceMigrationBuilder() (or CaseMigrationService entry point) instead of new CaseInstanceMigrationBuilderImpl()
  2. Inject/set the CmmnMigrationService on the builder instance if you must construct it manually
  3. 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

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


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)