flowable/flowable-engine · error · FlowableException
The deployment contains event definition with the same key…
Error message
The deployment contains event definition with the same key, this is not allowed
What it means
During event-registry deployment, Flowable scans all event definitions in the deployment and rejects duplicates: two definitions with the same key cannot coexist in one deployment. Event definitions are keyed by their 'key' attribute, which must be unique so persisted instances can be resolved unambiguously. The check uses a LinkedHashSet and throws on the first duplicate found.
Solutions
- Give every event definition JSON a unique 'key' value before deploying
- Remove the duplicate resource from the deployment (check the resources added to the DeploymentBuilder)
- If two definitions intentionally share a key, deploy them in separate deployments (versioning then applies)
- Search the deployment resources for duplicate key values with a pre-deploy validation script
Example fix
// before: deploy/events/orderCreated.event -> {"key":"orderCreated", ...}
// deploy/events/orderCreatedV2.event -> {"key":"orderCreated", ...}
// after
// deploy/events/orderCreatedV2.event -> {"key":"orderCreatedV2", ...} Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (EventDefinitionEntity def : eventDefinitions) {
if (!seen.add(def.getKey())) {
throw new IllegalArgumentException("Duplicate event key: " + def.getKey());
}
} Try / catch
try {
deploymentBuilder.deploy();
} catch (FlowableException e) {
if (e.getMessage().contains("same key")) { /* de-duplicate resources and retry */ }
} Prevention
- Enforce unique keys in event JSON files via a unit test scanning resources
- Name event files after their key to make duplicates obvious in review
- Adopt versioned keys (e.g. orderCreated.v2) instead of reusing keys
When it happens
Trigger: Calling deploy() (directly or via EventModelBuilder / repository deployer) with a deployment whose resource set contains two or more .event JSON files (or programmatically added definitions) that share the same key value.
Common situations: Copying an event JSON file to tweak it but forgetting to change its key; merging branches that each added a definition with the same key; a build script or test fixture accidentally packaging the same resource twice.
Related errors
- The deployment contains channel definition with the same…
- Could not find deployment with id
- Could not find deployment with id
- deployment does not exist:
- Deployment id is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/9e616ab23540f090.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/deployer/EventDefinitionDeploymentHelper.java:45
import org.flowable.eventregistry.impl.util.CommandContextUtil;
/**
* Methods for working with deployments. Much of the actual work of {@link EventDefinitionDeployer} is done by orchestrating the different pieces of work this class does; by having them here, we allow
* other deployers to make use of them.
*/
public class EventDefinitionDeploymentHelper {
/**
* Verifies that no two event definitions share the same key, to prevent database unique index violation.
*
* @throws FlowableException
* if any two event definitions have the same key
*/
public void verifyEventDefinitionsDoNotShareKeys(Collection<EventDefinitionEntity> eventDefinitions) {
Set<String> keySet = new LinkedHashSet<>();
for (EventDefinitionEntity eventDefinition : eventDefinitions) {
if (keySet.contains(eventDefinition.getKey())) {
throw new FlowableException("The deployment contains event definition with the same key, this is not allowed");
}
keySet.add(eventDefinition.getKey());
}
}
/**
* Updates all the event definition entities to match the deployment's values for tenant, engine version, and deployment id.
*/
public void copyDeploymentValuesToEventDefinitions(EventDeploymentEntity deployment, List<EventDefinitionEntity> eventDefinitions) {
String tenantId = deployment.getTenantId();
String deploymentId = deployment.getId();
for (EventDefinitionEntity eventDefinition : eventDefinitions) {
// event definition inherits the tenant id
if (tenantId != null) {
eventDefinition.setTenantId(tenantId);
}View on GitHub (pinned to d6d39ce1c6)