{"record":{"id":"55e83c7a108c8169","repo":"flowable/flowable-engine","slug":"the-channel-expression-tenant-detection-value-was","errorCode":null,"errorMessage":"The channel expression tenant detection value was not found for the channel model with key ${channelModel.key}. One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.","messagePattern":"The channel expression tenant detection value was not found for the channel model with key (.+?)\\. One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set\\.","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java","lineNumber":359,"sourceCode":"            eventKeyDetector = new XpathBasedInboundEventKeyDetector(keyDetection.getXmlXPathExpression());\n        } else {\n            throw new FlowableException(\n                \"The channel expression key detection value was not found for the channel model with key \" + channelModel.getKey()\n                    + \". One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.\");\n        }\n\n        ChannelEventTenantIdDetection channelEventTenantIdDetection = channelModel.getChannelEventTenantIdDetection();\n        if (channelEventTenantIdDetection != null) {\n            if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getDelegateExpression())) {\n                eventTenantDetector = resolveExpression(channelEventTenantIdDetection.getDelegateExpression(), InboundEventTenantDetector.class);\n            } else if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getFixedValue())) {\n                eventTenantDetector = new InboundEventStaticTenantDetector<>(channelEventTenantIdDetection.getFixedValue());\n            } else if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getJsonPointerExpression())) {\n                eventTenantDetector = new JsonPointerBasedInboundEventTenantDetector(channelEventTenantIdDetection.getJsonPointerExpression());\n            } else if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getxPathExpression())) {\n                eventTenantDetector = new XpathBasedInboundEventTenantDetector(channelEventTenantIdDetection.getxPathExpression());\n            } else {\n                throw new FlowableException(\n                    \"The channel expression tenant detection value was not found for the channel model with key \" + channelModel.getKey()\n                        + \". One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.\");\n            }\n        }\n\n        //noinspection unchecked\n        return new DefaultInboundEventProcessingPipeline(eventRepositoryService, eventDeserializer, eventFilter,\n            eventKeyDetector, eventTenantDetector, eventPayloadExtractor, eventTransformer, engineConfiguration);\n    }\n\n    protected <T> T resolveExpression(String expression, Class<T> type) {\n        Object value = CommandContextUtil.getEventRegistryConfiguration().getExpressionManager()\n            .createExpression(expression)\n            .getValue(new VariableContainerWrapper(Collections.emptyMap()));\n\n        if (type.isInstance(value)) {\n            return type.cast(value);\n        }","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java#L341-L377","documentation":"Analogous to key detection, inbound channels may declare how the tenant id is extracted from an event via ChannelEventTenantIdDetection. If such a detection object is present but none of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, or delegateExpression is populated, Flowable cannot build an InboundEventTenantDetector and throws this error in createExpressionEventProcessingPipeline.","triggerScenarios":"registerChannelModel on an inbound channel where channelModel.getChannelEventTenantIdDetection() is non-null but all its detection properties are empty, falling through the if/else-if chain to the throw.","commonSituations":"Adding a tenantIdDetection element to channel XML but leaving the attribute empty; builder call like keyDetectionTenantId() without arguments; copy-paste of channel config where the tenant detection values were removed.","solutions":["Populate one detection property on the ChannelEventTenantIdDetection, e.g. tenantIdDetectionFixedValue(\"tenant-1\") or tenantIdDetectionJsonField(\"tenantId\")","Remove the tenant detection entirely if tenant awareness is not needed for this channel (null detection is allowed)","If no static/expressed value fits, wire a custom InboundEventTenantDetector bean via delegateExpression"],"exampleFix":"// before\nChannelEventTenantIdDetection d = new ChannelEventTenantIdDetection();\nchannelModel.setChannelEventTenantIdDetection(d); // all fields empty\n// after\nChannelEventTenantIdDetection d = new ChannelEventTenantIdDetection();\nd.setFixedValue(\"acme\");\nchannelModel.setChannelEventTenantIdDetection(d);","handlingStrategy":"validation","validationCode":"ChannelEventTenantIdDetection d = channelModel.getChannelEventTenantIdDetection();\nif (d != null && (isEmpty(d.getFixedValue()) && isEmpty(d.getJsonField()) && isEmpty(d.getJsonPointerExpression()) && isEmpty(d.getxPathExpression()) && isEmpty(d.getDelegateExpression()))) {\n    throw new IllegalArgumentException(\"Channel '\" + channelModel.getKey() + \"' tenant detection has no value set\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Either fully configure tenant detection or omit it entirely (null is valid)","Use tenantIdDetectionFixedValue for single-tenant deployments","Test multi-tenant channel registration in a staging environment before production"],"tags":["flowable","event-registry","configuration","tenant"],"backgroundTag":"missing-required-config-field","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"}