{"record":{"id":"ce26d7f67029500c","repo":"flowable/flowable-engine","slug":"expected-expression-expression-to-resolve-to-ce26d7","errorCode":null,"errorMessage":"expected expression ${expression} to resolve to ${type} but it did not. Resolved value is ${value}","messagePattern":"expected expression (.+?) to resolve to (.+?) but it did not\\. Resolved value is (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/OutboundChannelModelProcessor.java","lineNumber":110,"sourceCode":"            }\n\n            if (eventProcessingPipeline != null) {\n                outboundChannelModel.setOutboundEventProcessingPipeline(eventProcessingPipeline);\n            }\n\n        }\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        }\n\n        throw new FlowableException(\"expected expression \" + expression + \" to resolve to \" + type + \" but it did not. Resolved value is \" + value);\n    }\n\n    @Override\n    public void unregisterChannelModel(ChannelModel channelModel, String tenantId, EventRepositoryService eventRepositoryService) {\n        // nothing to do\n    }\n}\n","sourceCodeStart":92,"sourceCodeEnd":118,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/OutboundChannelModelProcessor.java#L92-L118","documentation":"OutboundChannelModelProcessor.resolveExpression evaluates a delegate expression and checks that the resulting object is an instance of the requested type (typically OutboundEventSerializer). If the expression resolves to null or an object of a different type, this FlowableException is thrown rather than performing an unsafe cast.","triggerScenarios":"Outbound channel registration (registerChannelModel) or outboundEventSerializer resolution where a serializerDelegateExpression (or similar) resolves to a bean that is not an OutboundEventSerializer, or the expression evaluates to null.","commonSituations":"delegateExpression pointing at a bean of the wrong type (e.g. an InboundEventSerializer); bean name typo resolving to null; bean defined but not registered in the Spring context used by the event registry; custom serializer missing the interface.","solutions":["Ensure the bean referenced by the expression implements OutboundEventSerializer and fix the class if it does not","Verify the expression string and bean name match an actual bean in the application context","If the expression returns null, fix bean availability (component scan, conditional bean profiles) so it is created before channel registration"],"exampleFix":"// before\n@Bean\npublic JsonSerializer jsonSerializer() { ... } // not an OutboundEventSerializer\n// after\n@Bean\npublic OutboundEventSerializer jsonSerializer() { return new JacksonOutboundEventSerializer(objectMapper); }","handlingStrategy":"validation","validationCode":"Object bean = applicationContext.getBean(serializerBeanName);\nif (!(bean instanceof OutboundEventSerializer)) {\n    throw new IllegalArgumentException(serializerBeanName + \" must implement OutboundEventSerializer, got \" + bean.getClass());\n}","typeGuard":"boolean isSerializer = obj instanceof OutboundEventSerializer;","tryCatchPattern":"try {\n    registerChannelModel(...);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"expected expression\")) {\n        // verify serializer bean type/name\n    } else { throw e; }\n}","preventionTips":["Declare @Bean methods with OutboundEventSerializer as the return type","Avoid naming collisions between inbound and outbound serializer beans","Validate expressions resolve at startup with a health check"],"tags":["flowable","expression","type-mismatch","spring-bean"],"backgroundTag":"type-mismatch","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"}