flowable/flowable-engine · error · FlowableException
There are process definitions with key = '' and version =…
Error message
There are process definitions with key = '' and version = '' in tenant=''.
What it means
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.
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.
Example fix
// before // duplicates silently present for tenant 'acme' // after // DELETE FROM ACT_RE_PROCDEF WHERE KEY_='order' AND VERSION_=3 AND TENANT_ID_='acme' AND ID_ <> '<canonical-id>';
Defensive patterns
Strategy: validation
Validate before calling
long n = repositoryService.createProcessDefinitionQuery().processDefinitionTenantId(tenantId).processDefinitionKey(key).processDefinitionVersion(ver).count();
if (n > 1) throw new IllegalStateException("Duplicate definitions for tenant=" + tenantId + " key=" + key + " version=" + ver); Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- No process definition found for key
- Process definition with key
- There are process definitions with key = '' and version =…
- Async
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c93e15ef968c6561.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/data/impl/MybatisProcessDefinitionDataManager.java:150
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;
}
@Override
@SuppressWarnings("unchecked")
public List<ProcessDefinition> findProcessDefinitionsByNativeQuery(Map<String, Object> parameterMap) {
return getDbSqlSession().selectListWithRawParameter("selectProcessDefinitionByNativeQuery", parameterMap);
}
@Override
public long findProcessDefinitionCountByNativeQuery(Map<String, Object> parameterMap) {
return (Long) getDbSqlSession().selectOne("selectProcessDefinitionCountByNativeQuery", parameterMap);
}
@Override
public void updateProcessDefinitionTenantIdForDeployment(String deploymentId, String newTenantId) {
HashMap<String, Object> params = new HashMap<>();View on GitHub (pinned to d6d39ce1c6)