{"record":{"id":"0764a694fc749e9e","repo":"flowable/flowable-engine","slug":"tenant-mismatch-between-case-instance-caseinst","errorCode":null,"errorMessage":"Tenant mismatch between Case Instance ('${caseInstance.getTenantId()}') and Case Definition ('${destinationTenantId}') to migrate to","messagePattern":"Tenant mismatch between Case Instance \\('(.+?)'\\) and Case Definition \\('(.+?)'\\) to migrate to","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java","lineNumber":393,"sourceCode":"        if (migrationCallbacks != null && !migrationCallbacks.isEmpty()) {\n            CaseDefinition sourceCaseDefinition = CommandContextUtil.getCaseDefinitionEntityManager(commandContext).findById(originalCaseDefinitionId);\n            for (CaseInstanceMigrationCallback caseInstanceMigrationCallback : migrationCallbacks) {\n                caseInstanceMigrationCallback.historicCaseInstanceMigrated(historicCaseInstance, sourceCaseDefinition, caseDefinitionToMigrateTo, document);\n            }\n        }\n    }\n\n    protected ChangePlanItemStateBuilderImpl prepareChangeStateBuilder(CaseInstance caseInstance, CaseDefinition caseDefinitionToMigrateTo, \n            CaseInstanceMigrationDocument document, CommandContext commandContext) {\n        \n        String destinationTenantId = caseDefinitionToMigrateTo.getTenantId();\n        if (!Objects.equals(caseInstance.getTenantId(), destinationTenantId)) {\n            \n            CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n            if (cmmnEngineConfiguration.isFallbackToDefaultTenant() && cmmnEngineConfiguration.getDefaultTenantProvider() != null) {\n                \n                if (!Objects.equals(destinationTenantId, cmmnEngineConfiguration.getDefaultTenantProvider().getDefaultTenant(caseInstance.getTenantId(), ScopeTypes.CMMN, caseDefinitionToMigrateTo.getKey()))) {\n                    throw new FlowableException(\"Tenant mismatch between Case Instance ('\" + caseInstance.getTenantId() + \"') and Case Definition ('\" + destinationTenantId + \"') to migrate to\");\n                }\n            \n            } else {\n                throw new FlowableException(\"Tenant mismatch between Case Instance ('\" + caseInstance.getTenantId() + \"') and Case Definition ('\" + destinationTenantId + \"') to migrate to\");\n            }\n        }\n\n        String caseInstanceId = caseInstance.getId();\n        ChangePlanItemStateBuilderImpl changePlanItemStateBuilder = new ChangePlanItemStateBuilderImpl();\n        changePlanItemStateBuilder.caseInstanceId(caseInstanceId);\n\n        List<String> mappedPlanItemDefinitionIds = new ArrayList<>();\n        for (ActivatePlanItemDefinitionMapping planItemDefinitionMapping : document.getActivatePlanItemDefinitionMappings()) {\n            mappedPlanItemDefinitionIds.add(planItemDefinitionMapping.getPlanItemDefinitionId());\n            changePlanItemStateBuilder.activatePlanItemDefinition(planItemDefinitionMapping);\n        }\n        \n        for (TerminatePlanItemDefinitionMapping planItemDefinitionMapping : document.getTerminatePlanItemDefinitionMappings()) {","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java#L375-L411","documentation":"When changing plan item state (live case instance migration), Flowable validates the case instance's tenant against the destination case definition's tenant. On mismatch, it only allows the operation if fallback-to-default-tenant is enabled and the default tenant provider yields the destination tenant; otherwise this FlowableException is thrown.","triggerScenarios":"Calling CaseService/ChangePlanItemStateBuilder with a case definition whose tenantId differs from caseInstance.getTenantId(), while cmmnEngineConfiguration.isFallbackToDefaultTenant() is false or no DefaultTenantProvider is configured.","commonSituations":"Multi-tenant deployments where a case definition was re-deployed under another tenant; programmatic plan item state changes after tenant re-organization; migration tooling that omits the tenant id.","solutions":["Pass a destination case definition with the same tenant id as the running case instance.","Enable fallbackToDefaultTenant on CmmnEngineConfiguration and provide a DefaultTenantProvider resolving to the destination tenant.","Redeploy the target case definition under the case instance's tenant.","Verify the case instance tenant via the runtime service and align the change-state request."],"exampleFix":"// before\ncaseService.createChangePlanItemStateBuilder()\n    .movePlanItemIdTo(\"pi1\", \"newStage\"); // target def tenant 'b', instance tenant 'a'\n// after\ncmmnEngineConfiguration.setFallbackToDefaultTenant(true);\ncmmnEngineConfiguration.setDefaultTenantProvider(...); // resolve 'a' -> 'b' or align tenants","handlingStrategy":"validation","validationCode":"if (!Objects.equals(caseInstance.getTenantId(), destinationDefinition.getTenantId())) {\n    // align or ensure fallback config before invoking changePlanItemState\n}","typeGuard":null,"tryCatchPattern":"try { builder.changeState(); } catch (FlowableException e) { if (e.getMessage().contains(\"Tenant mismatch\")) { /* align tenants or configure provider */ } throw e; }","preventionTips":["Match destination definition tenant to the running case instance's tenant.","Configure and test DefaultTenantProvider when using fallback.","Avoid hardcoding tenant ids in change-state scripts.","Log both tenant ids before performing state changes."],"tags":["cmmn","tenant","migration","plan-item-state"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}