{"record":{"id":"5f4b514e97ab483e","repo":"flowable/flowable-engine","slug":"a-channel-key-detection-value-is-required-for-inbo","errorCode":null,"errorMessage":"A channel key detection value is required for inbound channel ${channelModel.key}","messagePattern":"A channel key detection value is required for inbound channel (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java","lineNumber":151,"sourceCode":"        }\n\n        InboundEventTenantDetector<JsonNode> eventTenantDetector = null; // By default no multi-tenancy is applied\n\n        JsonFieldToMapPayloadExtractor jsonFieldToMapPayloadExtractor = new JsonFieldToMapPayloadExtractor(engineConfiguration.getJsonPayloadValueTransformer());\n        InboundEventPayloadExtractor<JsonNode> eventPayloadExtractor = createInboundEventPayloadExtractor(channelModel, jsonFieldToMapPayloadExtractor);\n\n        InboundEventTransformer eventTransformer;\n        if (StringUtils.isEmpty(channelModel.getEventTransformerDelegateExpression())) {\n            eventTransformer = new DefaultInboundEventTransformer();\n        } else {\n            eventTransformer = resolveExpression(channelModel.getEventTransformerDelegateExpression(), InboundEventTransformer.class);\n        }\n\n        InboundEventKeyDetector<JsonNode> 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.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.getDelegateExpression())) {\n            //noinspection unchecked\n            eventKeyDetector = resolveExpression(keyDetection.getDelegateExpression(), InboundEventKeyDetector.class);\n        } else {\n            throw new FlowableException(\n                \"The channel json key detection value was not found for the channel model with key \" + channelModel.getKey()\n                    + \". One of fixedValue, jsonField, jsonPointerExpression or delegateExpression should be set.\");\n        }\n\n        ChannelEventTenantIdDetection channelEventTenantIdDetection = channelModel.getChannelEventTenantIdDetection();","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java#L133-L169","documentation":"Thrown when building a JSON event processing pipeline: an inbound channel model has no ChannelEventKeyDetection configured. The pipeline needs a key detector to map an incoming JSON event to a registered event definition, so registration cannot proceed without one.","triggerScenarios":"Registering a JSON inbound channel model (deserializeContentType application/json) where channelModel.getChannelEventKeyDetection() returns null — i.e. no keyDetection element/property set on the channel model.","commonSituations":"Hand-built InboundChannelModel missing setChannelEventKeyDetection; channel JSON/YAML model omitting the keyDetection section; copying a channel definition and dropping the key detection block.","solutions":["Set a ChannelEventKeyDetection on the channel model with one of: fixedValue, jsonField, jsonPointerExpression, or delegateExpression.","If the key is static per channel, use keyDetection.setFixedValue(\"my.event.key\").","If the key lives in a JSON field, use keyDetection.setJsonField(\"type\").","For dynamic detection, set keyDetection.setDelegateExpression(\"${myKeyDetector}\") pointing at an InboundEventKeyDetector bean."],"exampleFix":"// before\nInboundChannelModel channelModel = new InboundChannelModel();\nchannelModel.setKey(\"jsonChannel\");\n\n// after\nChannelEventKeyDetection keyDetection = new ChannelEventKeyDetection();\nkeyDetection.setJsonField(\"type\");\nchannelModel.setChannelEventKeyDetection(keyDetection);","handlingStrategy":"validation","validationCode":"if (channelModel.getChannelEventKeyDetection() == null) {\n    throw new IllegalArgumentException(\"Channel \" + channelModel.getKey() + \" needs a keyDetection\");\n}","typeGuard":"null","tryCatchPattern":"try {\n    eventRegistry.registerChannelModel(channelModel);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"channel key detection value is required\")) {\n        logger.error(\"Add keyDetection to channel {}\", channelModel.getKey());\n    }\n    throw e;\n}","preventionTips":["Always configure keyDetection when defining inbound channels","Use a shared channel-model builder/helper that enforces keyDetection","Validate channel model resources against the Flowable schema at build time"],"tags":["flowable","event-registry","missing-config","json-channel"],"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-18T11:17:12.947Z"}