{"record":{"id":"4eeac201b00da6bd","repo":"flowable/flowable-engine","slug":"must-specify-a-case-definition-tenant-id-to-migrat","errorCode":null,"errorMessage":"Must specify a case definition tenant id to migrate","messagePattern":"Must specify a case definition tenant id to migrate","errorType":"validation","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CaseInstanceMigrationBatchCmd.java","lineNumber":55,"sourceCode":"        if (caseDefinitionId == null) {\n            throw new FlowableException(\"Must specify a case definition id to migrate\");\n        }\n        if (caseInstanceMigrationDocument == null) {\n            throw new FlowableException(\"Must specify a case instance migration document to migrate\");\n        }\n        this.caseDefinitionId = caseDefinitionId;\n        this.caseInstanceMigrationDocument = caseInstanceMigrationDocument;\n        this.cmmnEngineConfiguration = cmmnEngineConfiguration;\n    }\n\n    public CaseInstanceMigrationBatchCmd(String caseDefinitionKey, int caseDefinitionVersion, String caseDefinitionTenantId, \n            CaseInstanceMigrationDocument caseInstanceMigrationDocument, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        \n        if (caseDefinitionKey == null) {\n            throw new FlowableException(\"Must specify a case definition id to migrate\");\n        }\n        if (caseDefinitionTenantId == null) {\n            throw new FlowableException(\"Must specify a case definition tenant id to migrate\");\n        }\n        if (caseInstanceMigrationDocument == null) {\n            throw new FlowableException(\"Must specify a case instance migration document to migrate\");\n        }\n        this.caseDefinitionKey = caseDefinitionKey;\n        this.caseDefinitionVersion = caseDefinitionVersion;\n        this.caseDefinitionTenantId = caseDefinitionTenantId;\n        this.caseInstanceMigrationDocument = caseInstanceMigrationDocument;\n        this.cmmnEngineConfiguration = cmmnEngineConfiguration;\n    }\n\n    @Override\n    public Batch execute(CommandContext commandContext) {\n        CaseInstanceMigrationManager migrationManager = cmmnEngineConfiguration.getCaseInstanceMigrationManager();\n\n        if (caseDefinitionId != null) {\n            return migrationManager.batchMigrateCaseInstancesOfCaseDefinition(caseDefinitionId, caseInstanceMigrationDocument, commandContext);\n        } else if (caseDefinitionKey != null && caseDefinitionVersion >= 0) {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CaseInstanceMigrationBatchCmd.java#L37-L73","documentation":"Constructor guard in CaseInstanceMigrationBatchCmd: when migrating by case definition key plus version, a tenant id must also be given; it is null, so the target definition cannot be identified unambiguously.","triggerScenarios":"Constructing new CaseInstanceMigrationBatchCmd(key, version, tenantId, document, config) with caseDefinitionTenantId == null. Note that a negative/unset version also blocks reaching this branch since the key check runs first.","commonSituations":"Single-tenant deployments where developers assume tenant is unnecessary and pass null; tenant id not propagated from the request context; default tenant stored as null in config.","solutions":["Pass the explicit tenant id of the target definition (e.g. \"\" for the default tenant or the configured tenant value)","Check your tenant provider/context resolution; ensure the id exists before building the command","If you have the definition id, use the id-based constructor which avoids key/version/tenant resolution"],"exampleFix":"// before\nnew CaseInstanceMigrationBatchCmd(\"myCase\", 2, tenantId, doc, config); // tenantId == null\n// after\nnew CaseInstanceMigrationBatchCmd(\"myCase\", 2, \"myTenant\", doc, config);","handlingStrategy":"validation","validationCode":"if (caseDefinitionTenantId == null) {\n    throw new IllegalArgumentException(\"Tenant id is required for key/version-based migration\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return new CaseInstanceMigrationBatchCmd(key, version, tenantId, document, config);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"tenant id\")) {\n        // supply default tenant or configured tenant and retry\n    }\n    throw e;\n}","preventionTips":["Always pass an explicit tenant id, even in single-tenant deployments","Centralize tenant resolution so it cannot be null at call sites","Prefer the id-based constructor to bypass tenant resolution entirely"],"tags":["cmmn","migration","tenant","null-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}