flowable/flowable-engine · error · FlowableException

Must specify a case definition tenant id to migrate

Error message

Must specify a case definition tenant id to migrate

What it means

When batch-migrating by case definition key and version, the tenant id is required to disambiguate the definition among tenants. The key/version/tenant constructor throws this FlowableException when caseDefinitionTenantId is null, because key+version alone may match definitions in multiple tenants.

Source

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

        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");
        }
        this.caseDefinitionKey = caseDefinitionKey;
        this.caseDefinitionVersion = caseDefinitionVersion;
        this.caseDefinitionTenantId = caseDefinitionTenantId;
        this.historicCaseInstanceMigrationDocument = historicCaseInstanceMigrationDocument;
        this.cmmnEngineConfiguration = cmmnEngineConfiguration;
    }

    @Override
    public Batch execute(CommandContext commandContext) {
        CaseInstanceMigrationManager migrationManager = cmmnEngineConfiguration.getCaseInstanceMigrationManager();

        if (caseDefinitionId != null) {
            return migrationManager.batchMigrateHistoricCaseInstancesOfCaseDefinition(caseDefinitionId, historicCaseInstanceMigrationDocument, commandContext);
        } else if (caseDefinitionKey != null && caseDefinitionVersion >= 0) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass the tenant id the case definition was deployed under (e.g. RepositoryService deploy artifacts with tenant, use the same value here).
  2. For single-tenant/no-tenant deployments, verify the deployed definition's tenant id via createCaseDefinitionQuery().caseDefinitionKey(key).caseDefinitionVersion(v).list() and use the value shown (often empty string or a default tenant).
  3. Alternatively migrate by explicit caseDefinitionId to avoid needing key/version/tenant at all.

Example fix

// before
new HistoricCaseInstanceMigrationBatchCmd("myCase", 3, null, doc, cfg); // tenant null

// after
new HistoricCaseInstanceMigrationBatchCmd("myCase", 3, "acme-tenant", doc, cfg);
Defensive patterns

Strategy: validation

Validate before calling

if (tenantId == null)
    throw new IllegalArgumentException("tenantId required for key-based historic migration");

Type guard

boolean hasTenant(String tenantId) { return tenantId != null; }

Try / catch

try {
    migrateByKeyVersionTenant(key, version, tenantId, doc);
} catch (FlowableException e) {
    if (e.getMessage().contains("tenant id")) {
        throw new ConfigurationException("Configure the deployment tenant id before migration", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling new HistoricCaseInstanceMigrationBatchCmd(caseDefinitionKey, version, null, document, cfg). Common when the application does not use multi-tenancy and the developer assumes tenant can be omitted.

Common situations: Single-tenant setups where tenant ids were never configured; passing empty string vs null confusion; copying a call that omitted the tenant argument.

Related errors


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