{"record":{"id":"247d533357257f4a","repo":"flowable/flowable-engine","slug":"the-channel-expression-key-detection-value-was-not","errorCode":null,"errorMessage":"The channel expression key 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 key 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":343,"sourceCode":"        InboundEventKeyDetector<?> eventKeyDetector;\n        ChannelEventKeyDetection keyDetection = channelModel.getChannelEventKeyDetection();\n\n        if (keyDetection == null) {\n            throw new FlowableException(\"A channel key detection value is required for inbound channel \" + channelModel.getKey());\n        }\n\n        if (StringUtils.isNotEmpty(keyDetection.getDelegateExpression())) {\n            eventKeyDetector = resolveExpression(keyDetection.getDelegateExpression(), InboundEventKeyDetector.class);\n        } else if (StringUtils.isNotEmpty(keyDetection.getFixedValue())) {\n            eventKeyDetector = new InboundEventStaticKeyDetector<>(keyDetection.getFixedValue());\n        } else if (StringUtils.isNotEmpty(keyDetection.getJsonField())) {\n            eventKeyDetector = new JsonFieldBasedInboundEventKeyDetector(keyDetection.getJsonField());\n        } else if (StringUtils.isNotEmpty(keyDetection.getJsonPointerExpression())) {\n            eventKeyDetector = new JsonPointerBasedInboundEventKeyDetector(keyDetection.getJsonPointerExpression(), objectMapper);\n        } else if (StringUtils.isNotEmpty(keyDetection.getXmlXPathExpression())) {\n            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.\");","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java#L325-L361","documentation":"When a channel model declares a ChannelEventKeyDetection but none of its detection properties (fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression) is set, no InboundEventKeyDetector can be constructed. Flowable throws this error during createExpressionEventProcessingPipeline. It is a validation that exactly one usable key detection strategy is configured.","triggerScenarios":"registerChannelModel on an inbound channel whose ChannelEventKeyDetection object exists but has all detection fields empty/null, so the if/else-if chain in createExpressionEventProcessingPipeline falls through to the else throw.","commonSituations":"Creating a keyDetection element in the channel model XML but leaving it empty; calling keyDetection() builder method without a value; serializing/deserializing the model and dropping field values; typos in the XML attribute name so the value lands on an unrecognized property.","solutions":["Set one of the supported detection values on the channel model: fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, or delegateExpression (e.g. keyDetectionJsonField(\"type\"))","Verify the serialized channel model resource actually contains the chosen value (e.g. <channelEventKeyDetection fixedValue=\"orderEvent\"/>) and redeploy","If detection logic is complex, implement an InboundEventKeyDetector bean and reference it with keyDetectionDelegateExpression(\"${myKeyDetector}\")"],"exampleFix":"// before\nChannelEventKeyDetection detection = new ChannelEventKeyDetection();\nchannelModel.setChannelEventKeyDetection(detection); // empty\n// after\nChannelEventKeyDetection detection = new ChannelEventKeyDetection();\ndetection.setJsonField(\"eventType\");\nchannelModel.setChannelEventKeyDetection(detection);","handlingStrategy":"validation","validationCode":"ChannelEventKeyDetection d = channelModel.getChannelEventKeyDetection();\nif (d == null || (isEmpty(d.getFixedValue()) && isEmpty(d.getJsonField()) && isEmpty(d.getJsonPointerExpression()) && isEmpty(d.getXmlXPathExpression()) && isEmpty(d.getDelegateExpression()))) {\n    throw new IllegalArgumentException(\"Channel '\" + channelModel.getKey() + \"' key detection has no detection value set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    eventRepositoryService.registerChannelModel(...);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"expression key detection value was not found\")) {\n        // fix channel model keyDetection config and redeploy\n    } else { throw e; }\n}","preventionTips":["Set exactly one key detection property per channel model","Check serialized channel model resources contain non-empty detection values","Prefer delegateExpression to a custom InboundEventKeyDetector for complex routing"],"tags":["flowable","event-registry","configuration","channel-model"],"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"}