{"record":{"id":"04f5d6fa682cf0e7","repo":"flowable/flowable-engine","slug":"there-are-app-definitions-with-key-and-versi","errorCode":null,"errorMessage":"There are  app definitions with key = '' and version = ''","messagePattern":"There are  app definitions with key = '' and version = ''","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/persistence/entity/data/impl/MybatisAppDefinitionDataManager.java","lineNumber":91,"sourceCode":"    @Override\n    public AppDefinitionEntity findAppDefinitionByDeploymentAndKeyAndTenantId(String deploymentId, String appDefinitionKey, String tenantId) {\n        Map<String, Object> parameters = new HashMap<>();\n        parameters.put(\"deploymentId\", deploymentId);\n        parameters.put(\"appDefinitionKey\", appDefinitionKey);\n        parameters.put(\"tenantId\", tenantId);\n        return (AppDefinitionEntity) getDbSqlSession().selectOne(\"selectAppDefinitionByDeploymentAndKeyAndTenantId\", parameters);\n    }\n\n    @Override\n    public AppDefinitionEntity findAppDefinitionByKeyAndVersion(String appDefinitionKey, Integer appDefinitionVersion) {\n        Map<String, Object> params = new HashMap<>();\n        params.put(\"appDefinitionKey\", appDefinitionKey);\n        params.put(\"appDefinitionVersion\", appDefinitionVersion);\n        List<AppDefinitionEntity> results = getDbSqlSession().selectList(\"selectAppDefinitionsByKeyAndVersion\", 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() + \" app definitions with key = '\" + appDefinitionKey + \"' and version = '\" + appDefinitionVersion + \"'.\");\n        }\n        return null;\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public AppDefinitionEntity findAppDefinitionByKeyAndVersionAndTenantId(String appDefinitionKey, Integer appDefinitionVersion, String tenantId) {\n        Map<String, Object> params = new HashMap<>();\n        params.put(\"appDefinitionKey\", appDefinitionKey);\n        params.put(\"appDefinitionVersion\", appDefinitionVersion);\n        params.put(\"tenantId\", tenantId);\n        List<AppDefinitionEntity> results = getDbSqlSession().selectList(\"selectAppDefinitionsByKeyAndVersionAndTenantId\", 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() + \" app definitions with key = '\" + appDefinitionKey + \"' and version = '\" + appDefinitionVersion + \"'.\");\n        }\n        return null;","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/persistence/entity/data/impl/MybatisAppDefinitionDataManager.java#L73-L109","documentation":"FlowableException thrown by MybatisAppDefinitionDataManager.findAppDefinitionByKeyAndVersion when the query selectAppDefinitionsByKeyAndVersion returns more than one row. The data layer expects (key, version) to be unique; duplicates indicate corrupted data, so it refuses to pick one arbitrarily.","triggerScenarios":"Calling an API that resolves an app definition by key+version when ACT_APP_APPDEF contains multiple rows with the same key and version — typically after manual inserts, failed migrations, or concurrent double-deployment bugs.","commonSituations":"Database manually edited or rows copied between environments; a broken import script inserted duplicates; historic Flowable bug or non-unique index in an old schema; tenant variants created where key+version uniqueness was assumed.","solutions":["Query the DB: SELECT * FROM ACT_APP_APPDEF WHERE KEY_ = ? AND VERSION_ = ? and delete/merge duplicates keeping the correct row","Add/restore the unique constraint on (KEY_, VERSION_) if your setup guarantees uniqueness","If duplicates are legitimate tenant variants, use the *AndTenantId lookup instead","Re-deploy the affected app after cleaning to ensure consistent state"],"exampleFix":"// before\n-- find duplicates\nSELECT KEY_, VERSION_, COUNT(*) FROM ACT_APP_APPDEF GROUP BY KEY_, VERSION_ HAVING COUNT(*) > 1;\n// after\n-- keep one row, remove the rest, then re-run the lookup","handlingStrategy":"try-catch","validationCode":"// detect duplicates before lookup\n// SELECT KEY_, VERSION_, COUNT(*) FROM ACT_APP_APPDEF GROUP BY KEY_, VERSION_ HAVING COUNT(*) > 1","typeGuard":null,"tryCatchPattern":"try {\n    AppDefinition def = ...findAppDefinitionByKeyAndVersion(key, version);\n} catch (FlowableException e) {\n    // clean duplicates in ACT_APP_APPDEF, then retry\n}","preventionTips":["Enforce DB unique constraint on (KEY_, VERSION_)","Never insert app definition rows manually","Use tenant-aware lookups when tenant variants exist"],"tags":["flowable","database","duplicate-rows","app-definition"],"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-14T05:17:10.506Z"}