flowable/flowable-engine · error · FlowableException

Must specify a historic case instance migration document to

Error message

Must specify a historic case instance migration document to migrate

What it means

The batch migration command needs a HistoricCaseInstanceMigrationDocument describing how historic case instances (and their plan items) map to the new case definition. If that document is null the constructor throws immediately, because a migration without mapping instructions is meaningless and would fail in the migration manager anyway.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/HistoricCaseInstanceMigrationBatchCmd.java:41

public class HistoricCaseInstanceMigrationBatchCmd implements Command<Batch> {

    protected CmmnEngineConfiguration cmmnEngineConfiguration;
    
    protected String caseDefinitionId;
    protected String caseDefinitionKey;
    protected int caseDefinitionVersion;
    protected String caseDefinitionTenantId;
    protected HistoricCaseInstanceMigrationDocument historicCaseInstanceMigrationDocument;

    public HistoricCaseInstanceMigrationBatchCmd(HistoricCaseInstanceMigrationDocument historicCaseInstanceMigrationDocument, String caseDefinitionId,
            CmmnEngineConfiguration cmmnEngineConfiguration) {
        
        if (caseDefinitionId == null) {
            throw new FlowableException("Must specify a case definition id to migrate");
        }
        if (historicCaseInstanceMigrationDocument == null) {
            throw new FlowableException("Must specify a historic case instance migration document to migrate");
        }
        this.caseDefinitionId = caseDefinitionId;
        this.historicCaseInstanceMigrationDocument = historicCaseInstanceMigrationDocument;
        this.cmmnEngineConfiguration = cmmnEngineConfiguration;
    }

    public HistoricCaseInstanceMigrationBatchCmd(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId, 
            HistoricCaseInstanceMigrationDocument historicCaseInstanceMigrationDocument, CmmnEngineConfiguration cmmnEngineConfiguration) {
        
        if (caseDefinitionKey == null) {
            throw new FlowableException("Must specify a case definition id to migrate");
        }
        if (caseDefinitionTenantId == null) {
            throw new FlowableException("Must specify a case definition tenant id to migrate");
        }
        if (historicCaseInstanceMigrationDocument == null) {
            throw new FlowableException("Must specify a historic case instance migration document to migrate");
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Build a migration document first via cmmnEngineConfiguration.getCaseInstanceMigrationManager() / HistoricCaseInstanceMigrationBuilder and pass its result.
  2. If loading from a file, parse it with HistoricCaseInstanceMigrationDocument.fromJson(json) and check the return value is non-null before constructing the command.
  3. Null-check the document before invoking the constructor.

Example fix

// before
HistoricCaseInstanceMigrationBatchCmd cmd =
    new HistoricCaseInstanceMigrationBatchCmd(caseDefId, migrationDoc, cfg); // migrationDoc == null

// after
HistoricCaseInstanceMigrationDocument migrationDoc = HistoricCaseInstanceMigrationDocument.fromJson(jsonString);
assert migrationDoc != null;
HistoricCaseInstanceMigrationBatchCmd cmd =
    new HistoricCaseInstanceMigrationBatchCmd(caseDefId, migrationDoc, cfg);
Defensive patterns

Strategy: validation

Validate before calling

if (migrationDocument == null)
    throw new IllegalArgumentException("Build HistoricCaseInstanceMigrationDocument before batch migration");

Type guard

boolean isReadyForBatch(HistoricCaseInstanceMigrationDocument doc, String defId) {
    return doc != null && defId != null;
}

Try / catch

try {
    execute(new HistoricCaseInstanceMigrationBatchCmd(doc, defId, cfg));
} catch (FlowableException e) {
    if (e.getMessage().contains("migration document")) {
        throw new ConfigurationException("Migration document missing; complete the builder chain", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling new HistoricCaseInstanceMigrationBatchCmd(caseDefinitionId, null, cmmnEngineConfiguration), e.g. forgetting to call HistoricCaseInstanceMigrationBuilder's mapping methods so createMigrationDocument()/the builder produced null, or passing an uninitialized field.

Common situations: Builder pattern misuse: creating the builder but never calling migrateCaseDefinitionTo(...)/map... methods before building; JSON migration document failed to parse and the variable stayed null; refactoring removed document construction.

Related errors


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