flowable/flowable-engine · error · FlowableException
There are event definitions with key = ' ' and version = '…
Error message
There are ${results.size()} event definitions with key = '${eventDefinitionKey}' and version = '${eventVersion}' in tenant = '${tenantId}'. What it means
Thrown by MybatisEventDefinitionDataManager.findEventDefinitionByKeyAndVersionAndTenantId when the tenant-scoped key+version query returns more than one row. In a multi-tenant setup, (TENANT_ID_, KEY_, VERSION_) must be unique; duplicates mean the same event definition version was persisted twice for that tenant.
Solutions
- Remove duplicate FLW_EV_DATABASE_DEFINITION rows matching the same TENANT_ID_, KEY_, VERSION_, keeping one.
- Make tenant bootstrap deployments idempotent: check EventDefinitionQuery for the tenant before deploying.
- Add a unique constraint on (TENANT_ID_, KEY_, VERSION_).
- Use a distributed lock or single deployer node for event registry deployments.
Example fix
// before
eventRepositoryService.createDeployment().addClasspathResource(res).tenantId(tenantId).deploy(); // all nodes
// after
if (eventRepositoryService.createEventDefinitionQuery().eventDefinitionKey(key)
.eventDefinitionVersion(version).tenantId(tenantId).count() == 0) {
eventRepositoryService.createDeployment().addClasspathResource(res).tenantId(tenantId).deploy();
} Defensive patterns
Strategy: validation
Validate before calling
long n = eventRepositoryService.createEventDefinitionQuery()
.eventDefinitionKey(key).eventDefinitionVersion(version).tenantId(tenantId).count();
if (n > 1) throw new IllegalStateException("duplicate tenant event definitions for " + key + " v" + version + " tenant " + tenantId); Try / catch
try {
def = manager.findEventDefinitionByKeyAndVersionAndTenantId(key, version, tenantId);
} catch (FlowableException e) {
def = dedupeTenantRowsAndRetry(key, version, tenantId);
} Prevention
- Add unique constraint on (TENANT_ID_, KEY_, VERSION_).
- Make per-tenant bootstrap deployment idempotent via existence checks.
- Use one deployer node or a lock for multi-tenant event deployments.
- Verify manual tenant data copies never duplicate rows within one tenant.
When it happens
Trigger: Concurrent per-tenant deployment of the same event model key/version on multiple nodes; both inserts commit and the next lookup throws FlowableException.
Common situations: Every application instance running tenant bootstrap deployment code at startup; duplicated migration scripts; manual copies of definition rows across tenants done incorrectly (same tenant twice).
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- There are event definitions with key = ' ' and version = '…
- There are event definitions with key = ' ' and version = '…
- Could not find a dataSource for tenant
- Could not resolve key for
- Error parsing event definition JSON
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/498833081aeba8c4.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/persistence/entity/data/impl/MybatisEventDefinitionDataManager.java:136
return results.get(0);
} else if (results.size() > 1) {
throw new FlowableException("There are " + results.size() + " event definitions with key = '" + eventDefinitionKey + "' and version = '" + eventVersion + "'.");
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public EventDefinitionEntity findEventDefinitionByKeyAndVersionAndTenantId(String eventDefinitionKey, Integer eventVersion, String tenantId) {
Map<String, Object> params = new HashMap<>();
params.put("eventDefinitionKey", eventDefinitionKey);
params.put("eventVersion", eventVersion);
params.put("tenantId", tenantId);
List<EventDefinitionEntity> results = getDbSqlSession().selectList("selectEventDefinitionsByKeyAndVersionAndTenantId", params);
if (results.size() == 1) {
return results.get(0);
} else if (results.size() > 1) {
throw new FlowableException("There are " + results.size() + " event definitions with key = '" + eventDefinitionKey + "' and version = '" + eventVersion + "' in tenant = '" + tenantId + "'.");
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public List<EventDefinition> findEventDefinitionsByNativeQuery(Map<String, Object> parameterMap) {
return getDbSqlSession().selectListWithRawParameter("selectEventDefinitionByNativeQuery", parameterMap);
}
@Override
public long findEventDefinitionCountByNativeQuery(Map<String, Object> parameterMap) {
return (Long) getDbSqlSession().selectOne("selectEventDefinitionCountByNativeQuery", parameterMap);
}
@Override
public void updateEventDefinitionTenantIdForDeployment(String deploymentId, String newTenantId) {
HashMap<String, Object> params = new HashMap<>();View on GitHub (pinned to d6d39ce1c6)