{"record":{"id":"0de277fa31d711a1","repo":"flowable/flowable-engine","slug":"a-channel-key-detection-value-is-required-for-the","errorCode":null,"errorMessage":"A channel key detection value is required for the channel model with key ${key}","messagePattern":"A channel key detection value is required for the channel model with key (.+?)","errorType":"validation","errorClass":"FlowableEventJsonException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry-json-converter/src/main/java/org/flowable/eventregistry/json/converter/InboundChannelModelValidator.java","lineNumber":45,"sourceCode":"        if (channelModel instanceof InboundChannelModel inboundChannelModel) {\n\n            validateChannel(inboundChannelModel);\n        }\n    }\n\n    protected void validateChannel(InboundChannelModel inboundChannelModel) {\n        if (StringUtils.isEmpty(inboundChannelModel.getPipelineDelegateExpression())) {\n            // Deserializer is only needed if there is no pipeline delegate expression\n            validateDeserializer(inboundChannelModel);\n        }\n    }\n\n    protected void validateDeserializer(InboundChannelModel inboundChannelModel) {\n        String deserializerType = inboundChannelModel.getDeserializerType();\n        ChannelEventKeyDetection channelEventKeyDetection = inboundChannelModel.getChannelEventKeyDetection();\n        if (\"json\".equalsIgnoreCase(deserializerType)) {\n            if (channelEventKeyDetection == null) {\n                throw new FlowableEventJsonException(\"A channel key detection value is required for the channel model with key \" + inboundChannelModel.getKey());\n            }\n\n            if (StringUtils.isEmpty(channelEventKeyDetection.getFixedValue()) &&\n                StringUtils.isEmpty(channelEventKeyDetection.getJsonField()) &&\n                StringUtils.isEmpty(channelEventKeyDetection.getJsonPointerExpression()) &&\n                StringUtils.isEmpty(channelEventKeyDetection.getDelegateExpression())) {\n                throw new FlowableEventJsonException(\n                    \"The channel json key detection value was not found for the channel model with key \" + inboundChannelModel.getKey()\n                        + \". One of fixedValue, jsonField, jsonPointerExpression, delegateExpression should be set.\");\n            }\n\n        } else if (\"xml\".equalsIgnoreCase(deserializerType)) {\n            if (channelEventKeyDetection == null) {\n                throw new FlowableEventJsonException(\"A channel key detection value is required for the channel model with key \" + inboundChannelModel.getKey());\n            }\n\n            if (StringUtils.isEmpty(channelEventKeyDetection.getFixedValue()) &&\n                StringUtils.isEmpty(channelEventKeyDetection.getXmlXPathExpression()) &&","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry-json-converter/src/main/java/org/flowable/eventregistry/json/converter/InboundChannelModelValidator.java#L27-L63","documentation":"Thrown by Flowable's inbound channel JSON converter when a channel model declares the 'json' deserializer type but has no ChannelEventKeyDetection configured. Key detection tells the event registry how to extract the event key from the JSON payload so it can match the payload to a registered event definition. Without it, the registry cannot classify incoming JSON payloads.","triggerScenarios":"Calling validateChannel/validateDeserializer on an InboundChannelModel whose deserializerType is 'json' and whose getChannelEventKeyDetection() returns null, e.g. an inbound channel JSON definition that omits the channelEventKeyDetection section.","commonSituations":"Hand-writing channel model JSON and forgetting the key detection block; converting channels from a fixed-key to a JSON-payload model without adding key detection; automated channel generation tools omitting the field.","solutions":["Add a channelEventKeyDetection section to the channel model JSON with one of fixedValue, jsonField, jsonPointerExpression, or delegateExpression","If the event key is known up front, set channelEventKeyDetection.fixedValue to the event definition key","Use channelEventKeyDetection.jsonField or jsonPointerExpression when the key is embedded in the payload","Provide channelEventKeyDetection.delegateExpression pointing at a bean implementing ChannelEventKeyDetection for custom logic"],"exampleFix":"// before\n{\n  \"key\": \"myChannel\",\n  \"deserializerType\": \"json\"\n}\n// after\n{\n  \"key\": \"myChannel\",\n  \"deserializerType\": \"json\",\n  \"channelEventKeyDetection\": {\n    \"jsonField\": \"type\"\n  }\n}","handlingStrategy":"validation","validationCode":"if (\"json\".equalsIgnoreCase(channel.getDeserializerType()) && channel.getChannelEventKeyDetection() == null) {\n    throw new IllegalArgumentException(\"channel '\" + channel.getKey() + \"' with json deserializer needs channelEventKeyDetection\");\n}","typeGuard":"boolean hasKeyDetection = c -> c.getChannelEventKeyDetection() != null;","tryCatchPattern":"try {\n    repositoryService.createEventRegistryChannelModelConverter().convertToChannelModel(json);\n} catch (FlowableEventJsonException e) {\n    logger.error(\"Channel model missing key detection: {}\", e.getMessage());\n}","preventionTips":["Always include a channelEventKeyDetection block when deserializerType is json","Validate channel model JSON against the Flowable JSON schema before deployment","Add unit tests that convert each channel definition with InboundChannelModelValidator"],"tags":["flowable","event-registry","validation","configuration"],"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-14T05:17:10.506Z"}