flowable/flowable-engine · error · FlowableObjectNotFoundException
No event definition found for key '${eventDefinitionKey}' fo
Error message
No event definition found for key '${eventDefinitionKey}' for tenant identifier '${tenantId}' What it means
When resolving by eventDefinitionKey with a specific tenantId, the manager finds the latest definition for key+tenant; if none exists the command throws FlowableObjectNotFoundException 'No event definition found for key <key> for tenant identifier <tenantId>'. The definition exists nowhere for that tenant combination.
Source
Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/cmd/GetEventModelCmd.java:94
throw new FlowableObjectNotFoundException("No event definition found for key '" + eventDefinitionKey + "'", EventDefinitionEntity.class);
}
} else if (eventDefinitionKey != null && tenantId != null && !EventRegistryEngineConfiguration.NO_TENANT_ID.equals(tenantId) &&
(parentDeploymentId == null || eventEngineConfiguration.isAlwaysLookupLatestDefinitionVersion())) {
eventDefinitionEntity = eventDefinitionEntityManager.findLatestEventDefinitionByKeyAndTenantId(eventDefinitionKey, tenantId);
if (eventDefinitionEntity == null && eventEngineConfiguration.isFallbackToDefaultTenant()) {
String defaultTenant = eventEngineConfiguration.getDefaultTenantProvider().getDefaultTenant(tenantId, ScopeTypes.EVENT_REGISTRY, eventDefinitionKey);
if (StringUtils.isNotEmpty(defaultTenant)) {
eventDefinitionEntity = eventDefinitionEntityManager.findLatestEventDefinitionByKeyAndTenantId(eventDefinitionKey, defaultTenant);
} else {
eventDefinitionEntity = eventDefinitionEntityManager.findLatestEventDefinitionByKey(eventDefinitionKey);
}
}
if (eventDefinitionEntity == null) {
throw new FlowableObjectNotFoundException("No event definition found for key '" + eventDefinitionKey + "' for tenant identifier '" + tenantId + "'", EventDefinitionEntity.class);
}
} else if (eventDefinitionKey != null && (tenantId == null || EventRegistryEngineConfiguration.NO_TENANT_ID.equals(tenantId)) && parentDeploymentId != null) {
List<EventDeployment> eventDeployments = deploymentManager.getDeploymentEntityManager().findDeploymentsByQueryCriteria(
new EventDeploymentQueryImpl().parentDeploymentId(parentDeploymentId));
if (eventDeployments != null && eventDeployments.size() > 0) {
eventDefinitionEntity = eventDefinitionEntityManager.findEventDefinitionByDeploymentAndKey(eventDeployments.get(0).getId(), eventDefinitionKey);
}
if (eventDefinitionEntity == null) {
eventDefinitionEntity = eventDefinitionEntityManager.findLatestEventDefinitionByKey(eventDefinitionKey);
}
if (eventDefinitionEntity == null) {
throw new FlowableObjectNotFoundException("No event definition found for key '" + eventDefinitionKey +
"' for parent deployment id " + parentDeploymentId, EventDefinitionEntity.class);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Deploy the event model for the requested tenant (deployment .tenantId(tenantId))
- Check existing definitions via createEventDefinitionQuery().eventDefinitionKey(key).tenantId(tenantId).list()
- Fix the tenantId string used at runtime to match the deployment tenant (or pass null/NO_TENANT_ID for the default tenant)
Example fix
// before
eventRepositoryService.getEventModelByKey("orderCreated", "acme"); // deployed without tenant
// after
eventRepositoryService.createDeployment()
.addClasspathResource("order-created.event.json")
.tenantId("acme")
.deploy();
eventRepositoryService.getEventModelByKey("orderCreated", "acme"); Defensive patterns
Strategy: validation
Validate before calling
EventDefinition def = eventRepositoryService.createEventDefinitionQuery()
.eventDefinitionKey(key).tenantId(tenantId).latestVersion().singleResult();
if (def == null) throw new IllegalArgumentException("No definition for key " + key + " and tenant " + tenantId); Type guard
boolean tenantDefinitionExists = eventRepositoryService.createEventDefinitionQuery()
.eventDefinitionKey(key).tenantId(tenantId).count() > 0; Try / catch
try {
return eventRepositoryService.getEventModelByKey(key, tenantId);
} catch (FlowableObjectNotFoundException e) {
log.warn("Missing event definition for tenant {}: {}", tenantId, e.getMessage());
throw e;
} Prevention
- Set .tenantId(...) on every tenant-scoped deployment
- Normalize tenant id casing centrally
- Deploy event models for each tenant during provisioning
- Fall back to default-tenant lookup only when explicitly intended
When it happens
Trigger: GetEventModelCmd with a tenantId set (not NO_TENANT_ID) and a key that has no definition deployed under that tenant — e.g. deployed only under tenant 'acme' but requested for tenant 'globex', or deployed with no tenant at all.
Common situations: Mismatched tenantId casing/spelling; deploying event models without setting the tenant while runtime requests a tenant; multi-tenant deployment where only some tenants received the model.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- No event definition found for id = ''
- No event definition found for key ''
- No event definition found for key '${eventDefinitionKey} for
- No event definition found for id = '${eventDefinitionId}'
- No decision found for key <decisionKey>. There was also no f
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/68d805c5f0b74b50.
Report an issue: GitHub.