flowable/flowable-engine · error · FlowableException
There are event definitions with key = ' ' and version = '…
Error message
There are ${results.size()} event definitions with key = '${channelDefinitionKey}' and version = '${eventVersion}'. What it means
Thrown by MybatisChannelDefinitionDataManager.findChannelDefinitionByKeyAndVersion when the query selectChannelDefinitionsByKeyAndVersion returns more than one row for a (key, version) pair. Since key+version should uniquely identify a channel definition, duplicates mean the data is inconsistent. Note the message misleadingly says 'event definitions' even for channels.
Solutions
- Find and remove the duplicate rows: SELECT * FROM FLW_EV_CHANNEL_DEFINITION WHERE KEY_ = ? AND VERSION_ > 1 order by ID_ and delete the extras.
- Serialize deployments of the same key (e.g. distributed lock) so two nodes cannot insert the same version concurrently.
- Add a unique DB constraint on (KEY_, VERSION_) (and TENANT_ID_ where applicable) to fail fast on duplicates.
- Reconcile duplicates by keeping the definition whose DEPLOYMENT_ID_ matches the surviving deployment.
Example fix
-- before (duplicates present) SELECT * FROM FLW_EV_CHANNEL_DEFINITION WHERE KEY_='myChannel' AND VERSION_=1; -- after: keep one row, delete others DELETE FROM FLW_EV_CHANNEL_DEFINITION WHERE KEY_='myChannel' AND VERSION_=1 AND ID_ != '<kept-id>';
Defensive patterns
Strategy: validation
Validate before calling
long n = eventRepositoryService.createChannelDefinitionQuery()
.channelKey(key).channelDefinitionVersion(version).count();
if (n > 1) throw new IllegalStateException("duplicate channel definitions for key " + key + " v" + version + ", clean DB before lookup"); Try / catch
try {
ch = manager.findChannelDefinitionByKeyAndVersion(key, version);
} catch (FlowableException e) {
ch = dedupeAndRetry(key, version); // remove duplicate rows, then retry
} Prevention
- Add unique constraint on FLW_EV_CHANNEL_DEFINITION (KEY_, VERSION_).
- Serialize deployments of the same channel key across cluster nodes.
- Avoid manual inserts into event registry tables.
- Run a duplicate-detection query as part of health checks.
When it happens
Trigger: More than one FLW_EV_CHANNEL_DEFINITION row shares the same KEY_ and VERSION_ — typically from concurrent deployments of the same channel model racing to insert the same version number.
Common situations: Multiple cluster nodes deploying the same channel resource simultaneously without unique constraints or synchronization; manual DB inserts; retry logic re-inserting after a partial commit.
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 = '…
- Channel definition id is null
- channelDefinitionKey and channelDefinitionId are null
- couldn't deduct database type from database product name
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0465ab5012320d38.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/persistence/entity/data/impl/MybatisChannelDefinitionDataManager.java:117
public ChannelDefinitionEntity findChannelDefinitionByDeploymentAndKeyAndTenantId(String deploymentId, String channelDefinitionKey, String tenantId) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("deploymentId", deploymentId);
parameters.put("channelDefinitionKey", channelDefinitionKey);
parameters.put("tenantId", tenantId);
return (ChannelDefinitionEntity) getDbSqlSession().selectOne("selectChannelDefinitionByDeploymentAndKeyAndTenantId", parameters);
}
@Override
@SuppressWarnings("unchecked")
public ChannelDefinitionEntity findChannelDefinitionByKeyAndVersion(String channelDefinitionKey, Integer eventVersion) {
Map<String, Object> params = new HashMap<>();
params.put("channelDefinitionKey", channelDefinitionKey);
params.put("eventVersion", eventVersion);
List<ChannelDefinitionEntity> results = getDbSqlSession().selectList("selectChannelDefinitionsByKeyAndVersion", 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 = '" + channelDefinitionKey + "' and version = '" + eventVersion + "'.");
}
return null;
}
@Override
@SuppressWarnings("unchecked")
public ChannelDefinitionEntity findChannelDefinitionByKeyAndVersionAndTenantId(String channelDefinitionKey, Integer eventVersion, String tenantId) {
Map<String, Object> params = new HashMap<>();
params.put("channelDefinitionKey", channelDefinitionKey);
params.put("eventVersion", eventVersion);
params.put("tenantId", tenantId);
List<ChannelDefinitionEntity> results = getDbSqlSession().selectList("selectChannelDefinitionsByKeyAndVersionAndTenantId", 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 = '" + channelDefinitionKey + "' and version = '" + eventVersion + "' in tenant = '" + tenantId + "'.");
}
return null;View on GitHub (pinned to d6d39ce1c6)