{"record":{"id":"be350e74deebf366","repo":"flowable/flowable-engine","slug":"the-channel-deserializer-delegate-expression-was-n","errorCode":null,"errorMessage":"The channel deserializer delegate expression was not set for the channel model with key ${channelModel}","messagePattern":"The channel deserializer delegate expression was not set 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":72,"sourceCode":"                        + \". 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()) &&\n                StringUtils.isEmpty(channelEventKeyDetection.getDelegateExpression())) {\n                throw new FlowableEventJsonException(\n                    \"The channel xml key detection value was not found for the channel model with key \" + inboundChannelModel.getKey()\n                        + \". One of fixedValue, xmlPathExpression, delegateExpression should be set.\");\n            }\n\n        } else if (\"expression\".equalsIgnoreCase(deserializerType)) {\n            if (StringUtils.isEmpty(inboundChannelModel.getDeserializerDelegateExpression())) {\n                throw new FlowableEventJsonException(\n                    \"The channel deserializer delegate expression was not set for the channel model with key \" + inboundChannelModel);\n            }\n        } else if (deserializerType != null) {\n            throw new FlowableEventJsonException(\n                \"The deserializer type is not supported \" + deserializerType + \" for the channel model with key \" + inboundChannelModel.getKey());\n        }\n    }\n}\n","sourceCodeStart":54,"sourceCodeEnd":81,"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#L54-L81","documentation":"Thrown when an inbound channel declares deserializerType 'expression' but no deserializerDelegateExpression is set. The 'expression' deserializer delegates payload deserialization to a custom bean, so its delegate expression is mandatory.","triggerScenarios":"validateDeserializer runs on a channel with deserializerType 'expression' and StringUtils.isEmpty(inboundChannelModel.getDeserializerDelegateExpression()) is true.","commonSituations":"Choosing the 'expression' deserializer type in the channel JSON and forgetting deserializerDelegateExpression; renaming the Spring bean without updating the expression.","solutions":["Set deserializerDelegateExpression in the channel model, e.g. \"${myDeserializerBean}\"","Ensure the referenced bean exists in the application context and implements the deserializer delegate interface","Alternatively switch deserializerType to 'json' or 'xml' if built-in deserialization suffices"],"exampleFix":"// before\n{\n  \"key\": \"customChannel\",\n  \"deserializerType\": \"expression\"\n}\n// after\n{\n  \"key\": \"customChannel\",\n  \"deserializerType\": \"expression\",\n  \"deserializerDelegateExpression\": \"${myPayloadDeserializer}\"\n}","handlingStrategy":"validation","validationCode":"if (\"expression\".equalsIgnoreCase(channel.getDeserializerType()) && (channel.getDeserializerDelegateExpression() == null || channel.getDeserializerDelegateExpression().isEmpty())) {\n    throw new IllegalArgumentException(\"channel '\" + channel.getKey() + \"' with expression deserializer needs deserializerDelegateExpression\");\n}","typeGuard":"boolean hasDeserializerDelegate = c -> !\"expression\".equalsIgnoreCase(c.getDeserializerType()) || isSet(c.getDeserializerDelegateExpression());","tryCatchPattern":"try {\n    convertChannel(channelJson);\n} catch (FlowableEventJsonException e) {\n    logger.error(\"Deserializer delegate expression missing: {}\", e.getMessage());\n}","preventionTips":["Whenever deserializerType is expression, immediately add deserializerDelegateExpression","Confirm the referenced bean name exists in the Spring context","Add a startup-time validation test for all channel definitions"],"tags":["flowable","event-registry","validation","missing-expression"],"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"}