{"record":{"id":"d0a44b9985b367d5","repo":"flowable/flowable-engine","slug":"no-channel-definition-found-for-key-for-tenant","errorCode":null,"errorMessage":"No channel definition found for key '' for tenant identifier ","messagePattern":"No channel definition found for key '' for tenant identifier ","errorType":"exception","errorClass":"FlowableObjectNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/cmd/GetChannelModelCmd.java","lineNumber":94,"sourceCode":"                throw new FlowableObjectNotFoundException(\"No channel definition found for key '\" + channelDefinitionKey + \"'\", ChannelDefinitionEntity.class);\n            }\n\n        } else if (channelDefinitionKey != null && tenantId != null && !EventRegistryEngineConfiguration.NO_TENANT_ID.equals(tenantId) && \n                        (parentDeploymentId == null || eventEngineConfiguration.isAlwaysLookupLatestDefinitionVersion())) {\n\n            channelDefinitionEntity = channelDefinitionEntityManager.findLatestChannelDefinitionByKeyAndTenantId(channelDefinitionKey, tenantId);\n            \n            if (channelDefinitionEntity == null && eventEngineConfiguration.isFallbackToDefaultTenant()) {\n                String defaultTenant = eventEngineConfiguration.getDefaultTenantProvider().getDefaultTenant(tenantId, ScopeTypes.EVENT_REGISTRY, channelDefinitionKey);\n                if (StringUtils.isNotEmpty(defaultTenant)) {\n                    channelDefinitionEntity = channelDefinitionEntityManager.findLatestChannelDefinitionByKeyAndTenantId(channelDefinitionKey, defaultTenant);\n                } else {\n                    channelDefinitionEntity = channelDefinitionEntityManager.findLatestChannelDefinitionByKey(channelDefinitionKey);\n                }\n            }\n\n            if (channelDefinitionEntity == null) {\n                throw new FlowableObjectNotFoundException(\"No channel definition found for key '\" + channelDefinitionKey + \"' for tenant identifier \" + tenantId, ChannelDefinitionEntity.class);\n            }\n\n        } else if (channelDefinitionKey != null && (tenantId == null || EventRegistryEngineConfiguration.NO_TENANT_ID.equals(tenantId)) && parentDeploymentId != null) {\n\n            List<EventDeployment> eventDeployments = deploymentManager.getDeploymentEntityManager().findDeploymentsByQueryCriteria(\n                            new EventDeploymentQueryImpl().parentDeploymentId(parentDeploymentId));\n            \n            if (eventDeployments != null && eventDeployments.size() > 0) {\n                channelDefinitionEntity = channelDefinitionEntityManager.findChannelDefinitionByDeploymentAndKey(eventDeployments.get(0).getId(), channelDefinitionKey);\n            }\n            \n            if (channelDefinitionEntity == null) {\n                channelDefinitionEntity = channelDefinitionEntityManager.findLatestChannelDefinitionByKey(channelDefinitionKey);\n            }\n            \n            if (channelDefinitionEntity == null) {\n                throw new FlowableObjectNotFoundException(\"No channel definition found for key '\" + channelDefinitionKey +\n                        \"' for parent deployment id \" + parentDeploymentId, ChannelDefinitionEntity.class);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/cmd/GetChannelModelCmd.java#L76-L112","documentation":"Thrown when resolving a channel definition by key for a specific tenantId and no deployed definition exists for that key+tenant combination. FlowableObjectNotFoundException including the tenant identifier.","triggerScenarios":"getChannelModel with channelDefinitionKey plus a non-null tenantId (not NO_TENANT_ID) where findLatestChannelDefinitionByKeyAndTenantId returns nothing — the channel was deployed without that tenant id or without tenant isolation.","commonSituations":"Deploying channel definitions without setting the tenant id in the deployment while the runtime lookup passes a tenant; tenant name mismatch (case/prefix); multi-tenant data not provisioned for a new tenant.","solutions":["Deploy the channel definition with the same tenantId passed at lookup time (DeploymentBuilder.tenantId(...))","Verify the exact tenant id string in the database matches the lookup value","If the channel is tenant-agnostic, look up without a tenant or use the engine's NO_TENANT_ID value"],"exampleFix":"// before\nrepositoryService.createDeployment().addClasspathResource(\"sms-channel.xml\").deploy(); // no tenant\ngetChannelModel(\"sms-channel\", null, \"acme\"); // looks up tenant 'acme' -> not found\n// after\nrepositoryService.createDeployment().addClasspathResource(\"sms-channel.xml\").tenantId(\"acme\").deploy();\ngetChannelModel(\"sms-channel\", null, \"acme\");","handlingStrategy":"validation","validationCode":"ChannelDefinition cd = repositoryService.createChannelDefinitionQuery()\n    .channelDefinitionKey(key).latest().singleResult(); // tenant-filtered variant if available\nif (cd == null) throw new IllegalStateException(\"channel \" + key + \" not deployed for tenant \" + tenantId);","typeGuard":null,"tryCatchPattern":"try {\n    return repositoryService.getChannelModel(null, key, tenantId, null);\n} catch (FlowableObjectNotFoundException e) {\n    LOGGER.error(\"channel {} missing for tenant {}\", key, tenantId);\n    throw e;\n}","preventionTips":["Always set tenantId on the DeploymentBuilder when the runtime uses tenant-scoped lookups","Use one constant/property source for tenant ids across deploy and lookup code","Provision tenant data as part of tenant onboarding"],"tags":["flowable","not-found","channel","tenant","multi-tenancy"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}