{"record":{"id":"c93e15ef968c6561","repo":"flowable/flowable-engine","slug":"there-are-process-definitions-with-key-and-v-c93e15","errorCode":null,"errorMessage":"There are  process definitions with key = '' and version = '' in tenant=''.","messagePattern":"There are  process definitions with key = '' and version = '' in tenant=''\\.","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/data/impl/MybatisProcessDefinitionDataManager.java","lineNumber":150,"sourceCode":"            return results.get(0);\n        } else if (results.size() > 1) {\n            throw new FlowableException(\"There are \" + results.size() + \" process definitions with key = '\" + processDefinitionKey + \"' and version = '\" + processDefinitionVersion + \"'.\");\n        }\n        return null;\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public ProcessDefinitionEntity findProcessDefinitionByKeyAndVersionAndTenantId(String processDefinitionKey, Integer processDefinitionVersion, String tenantId) {\n        Map<String, Object> params = new HashMap<>();\n        params.put(\"processDefinitionKey\", processDefinitionKey);\n        params.put(\"processDefinitionVersion\", processDefinitionVersion);\n        params.put(\"tenantId\", tenantId);\n        List<ProcessDefinitionEntity> results = getDbSqlSession().selectList(\"selectProcessDefinitionsByKeyAndVersionAndTenantId\", params);\n        if (results.size() == 1) {\n            return results.get(0);\n        } else if (results.size() > 1) {\n            throw new FlowableException(\"There are \" + results.size() + \" process definitions with key = '\" + processDefinitionKey + \"' and version = '\" + processDefinitionVersion + \"' in tenant='\" + tenantId + \"'.\");\n        }\n        return null;\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public List<ProcessDefinition> findProcessDefinitionsByNativeQuery(Map<String, Object> parameterMap) {\n        return getDbSqlSession().selectListWithRawParameter(\"selectProcessDefinitionByNativeQuery\", parameterMap);\n    }\n\n    @Override\n    public long findProcessDefinitionCountByNativeQuery(Map<String, Object> parameterMap) {\n        return (Long) getDbSqlSession().selectOne(\"selectProcessDefinitionCountByNativeQuery\", parameterMap);\n    }\n\n    @Override\n    public void updateProcessDefinitionTenantIdForDeployment(String deploymentId, String newTenantId) {\n        HashMap<String, Object> params = new HashMap<>();","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/data/impl/MybatisProcessDefinitionDataManager.java#L132-L168","documentation":"findProcessDefinitionByKeyAndVersionAndTenantId expects exactly one process definition for the given key, version and tenant id. If the query returns multiple rows, the tenant-scoped definition data is duplicated/inconsistent, so a FlowableException is thrown with the count, key, version and tenant id.","triggerScenarios":"Tenant-aware definition resolution (deployments or runtime lookups by key+version+tenantId) when ACT_RE_PROCDEF holds duplicate rows for the same KEY_, VERSION_ and TENANT_ID_, typically after manual data changes or environment merges.","commonSituations":"Multi-tenant setups where the same definition was (re)inserted manually per tenant; database merges restoring duplicate rows; a deployment bug in old versions racing on tenant-scoped versioning; case where tenant rows also collide with the default-tenant rows.","solutions":["Query ACT_RE_PROCDEF with KEY_, VERSION_ and TENANT_ID_ filters, remove duplicates keeping a single canonical row.","Redeploy cleanly for that tenant to regenerate a consistent definition row, then migrate/repoint any instances referencing the duplicate.","Guard deployment tooling so only the engine assigns versions; never INSERT into ACT_RE_PROCDEF manually.","If duplicates are pervasive, restore ACT_RE_PROCDEF (and related tables) from a consistent backup."],"exampleFix":"// before\n// duplicates silently present for tenant 'acme'\n// after\n// DELETE FROM ACT_RE_PROCDEF WHERE KEY_='order' AND VERSION_=3 AND TENANT_ID_='acme' AND ID_ <> '<canonical-id>';","handlingStrategy":"validation","validationCode":"long n = repositoryService.createProcessDefinitionQuery().processDefinitionTenantId(tenantId).processDefinitionKey(key).processDefinitionVersion(ver).count();\nif (n > 1) throw new IllegalStateException(\"Duplicate definitions for tenant=\" + tenantId + \" key=\" + key + \" version=\" + ver);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep tenant-scoped definitions unique; redeploy cleanly instead of copying rows","Include TENANT_ID_ in integrity audits of ACT_RE_PROCDEF","Let the engine assign versions during deployment"],"tags":["process-definition","multi-tenant","data-integrity"],"backgroundTag":"internal-invariant-violation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}