flowable/flowable-engine · error · FlowableException
expected expression ${expression} to resolve to ${type} but
Error message
expected expression ${expression} to resolve to ${type} but it did not. Resolved value is ${value} What it means
InboundChannelModelProcessor.resolveExpression evaluates a delegate expression (e.g. a Spring/el bean reference) and verifies the resolved value is an instance of the requested type (such as InboundEventKeyDetector, InboundEventSerializer, or a payload extractor). If the expression resolves to something of a different type (or null), Flowable throws this FlowableException instead of returning a bad cast.
Source
Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java:379
+ ". One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.");
}
}
//noinspection unchecked
return new DefaultInboundEventProcessingPipeline(eventRepositoryService, eventDeserializer, eventFilter,
eventKeyDetector, eventTenantDetector, eventPayloadExtractor, eventTransformer, engineConfiguration);
}
protected <T> T resolveExpression(String expression, Class<T> type) {
Object value = CommandContextUtil.getEventRegistryConfiguration().getExpressionManager()
.createExpression(expression)
.getValue(new VariableContainerWrapper(Collections.emptyMap()));
if (type.isInstance(value)) {
return type.cast(value);
}
throw new FlowableException("expected expression " + expression + " to resolve to " + type + " but it did not. Resolved value is " + value);
}
@Override
public void unregisterChannelModel(ChannelModel channelModel, String tenantId, EventRepositoryService eventRepositoryService) {
// nothing to do
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Make the referenced bean implement the exact expected interface (e.g. implements InboundEventKeyDetector) and redeploy
- Check the expression string for typos and confirm it points at the intended bean; verify the bean exists in the application context and is of the expected type
- Log the resolved value's class at that expression to diagnose the mismatch, then correct the configuration or the bean
Example fix
// before
@Bean
public Object orderKeyDetector() { return new OrderKeyResolver(); } // wrong type
// after
@Bean
public InboundEventKeyDetector orderKeyDetector() { return new OrderKeyResolver(); } // implements InboundEventKeyDetector Defensive patterns
Strategy: validation
Validate before calling
Object resolved = applicationContext.getBean(beanName);
if (!(resolved instanceof InboundEventKeyDetector)) {
throw new IllegalArgumentException(beanName + " must implement InboundEventKeyDetector, got " + resolved.getClass());
} Type guard
boolean validDelegate = obj instanceof InboundEventKeyDetector;
Try / catch
try {
registerChannelModel(channelModel, tenantId, repoService);
} catch (FlowableException e) {
if (e.getMessage().startsWith("expected expression")) {
// inspect bean type behind the delegateExpression
} else { throw e; }
} Prevention
- Type delegate beans as the exact Flowable interface in @Bean method return types
- Ensure referenced beans exist in the context before channel registration
- Smoke-test delegate expressions at application startup
When it happens
Trigger: Any channel registration/pipeline creation that resolves a delegateExpression — e.g. serializerDelegateExpression, keyDetector delegateExpression, payload extractor expression — where the bean behind the expression does not implement/extend the expected interface, or the expression evaluates to null.
Common situations: Pointing a delegateExpression at the wrong Spring bean (right name, wrong type); bean of a compatible-looking custom class that does not implement Flowable's interface; expression typo resolving to a String; bean not yet created so expression resolves null.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- expected expression ${expression} to resolve to ${type} but
- decisionTableReferenceKey expression does not resolve to a s
- Skip expression does not resolve to a boolean: " + skipExpre
- Unable to resolve formFieldValidationExpression to boolean v
- DelegateExpression inbound channel model with key ${channelM
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/351f5df7b6e8ee95.
Report an issue: GitHub.