flowable/flowable-engine · error · FlowableException
There are process definitions with key = '' and version =…
Error message
There are process definitions with key = '' and version = ''.
What it means
findProcessDefinitionByKeyAndVersion expects at most one process definition for a given key and version. If the query 'selectProcessDefinitionsByKeyAndVersion' returns more than one row, the data is inconsistent (duplicated definitions for the same key/version) and a FlowableException is thrown listing the count, key and version.
Solutions
- Inspect ACT_RE_PROCDEF: SELECT * FROM ACT_RE_PROCDEF WHERE KEY_ = '<key>' AND VERSION_ = <version>; delete/archive duplicate rows keeping exactly one.
- Identify how duplicates were created (manual inserts, DB merge) and prevent it; rely on engine-generated versioning only.
- If multi-tenant, use the tenant-aware lookup (findProcessDefinitionByKeyAndVersionAndTenantId) or include tenant id in queries.
- Restore from a clean backup of ACT_RE_PROCDEF if duplicates are widespread.
Example fix
// before ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).processDefinitionVersion(ver).singleResult(); // may hide duplicates // after: dedupe in DB // DELETE FROM ACT_RE_PROCDEF WHERE ID_ = '<duplicate-id>'; -- keep one row per (KEY_, VERSION_)
Defensive patterns
Strategy: validation
Validate before calling
long n = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).processDefinitionVersion(ver).count();
if (n > 1) throw new IllegalStateException("Duplicate process definitions for key=" + key + " version=" + ver);
if (n == 0) throw new IllegalStateException("No process definition for key=" + key + " version=" + ver); Prevention
- Never manually INSERT into ACT_RE_PROCDEF
- Audit the table for duplicate (KEY_, VERSION_) pairs after restores/merges
- Use engine-managed versioning via deployments only
When it happens
Trigger: Calling RepositoryService.getProcessDefinitionByKeyAndVersion-style lookups (or deployment resolution paths using this manager method) when the ACT_RE_PROCDEF table contains duplicate rows with the same KEY_ and VERSION_ — e.g. after a bad restore, manual data manipulation, or deployment concurrency bugs in older versions.
Common situations: Database restored/merged from two environments producing duplicate definition rows; manual SQL inserts into ACT_RE_PROCDEF; a historical Flowable bug or concurrent deployment race creating duplicates; tenant mismatches where the non-tenant lookup hits multi-tenant rows.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot get process definition for id for
- deployment for process definition does not exist
- There are process definitions with key = '' and version =…
- ActivityInstance not found for
- Async
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0cc98012b9267a50.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/data/impl/MybatisProcessDefinitionDataManager.java:134
@Override
public ProcessDefinitionEntity findProcessDefinitionByParentDeploymentAndKeyAndTenantId(String parentDeploymentId, String processDefinitionKey, String tenantId) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("parentDeploymentId", parentDeploymentId);
parameters.put("processDefinitionKey", processDefinitionKey);
parameters.put("tenantId", tenantId);
return (ProcessDefinitionEntity) getDbSqlSession().selectOne("selectProcessDefinitionByParentDeploymentAndKeyAndTenantId", parameters);
}
@Override
public ProcessDefinitionEntity findProcessDefinitionByKeyAndVersion(String processDefinitionKey, Integer processDefinitionVersion) {
Map<String, Object> params = new HashMap<>();
params.put("processDefinitionKey", processDefinitionKey);
params.put("processDefinitionVersion", processDefinitionVersion);
List<ProcessDefinitionEntity> results = getDbSqlSession().selectList("selectProcessDefinitionsByKeyAndVersion", params);
if (results.size() == 1) {
return results.get(0);
} else if (results.size() > 1) {
throw new FlowableException("There are " + results.size() + " process definitions with key = '" + processDefinitionKey + "' and version = '" + processDefinitionVersion + "'.");
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public ProcessDefinitionEntity findProcessDefinitionByKeyAndVersionAndTenantId(String processDefinitionKey, Integer processDefinitionVersion, String tenantId) {
Map<String, Object> params = new HashMap<>();
params.put("processDefinitionKey", processDefinitionKey);
params.put("processDefinitionVersion", processDefinitionVersion);
params.put("tenantId", tenantId);
List<ProcessDefinitionEntity> results = getDbSqlSession().selectList("selectProcessDefinitionsByKeyAndVersionAndTenantId", params);
if (results.size() == 1) {
return results.get(0);
} else if (results.size() > 1) {
throw new FlowableException("There are " + results.size() + " process definitions with key = '" + processDefinitionKey + "' and version = '" + processDefinitionVersion + "' in tenant='" + tenantId + "'.");
}
return null;View on GitHub (pinned to d6d39ce1c6)