flowable/flowable-engine · error · IllegalArgumentException
ackMode in definition [ <channelDefinition> ] must resolve t
Error message
ackMode in definition [ <channelDefinition> ] must resolve to a String or AcknowledgeMode
What it means
The ackMode attribute of a Rabbit inbound channel definition, when set (even as an expression), must resolve to either a String naming an AcknowledgeMode enum value or an AcknowledgeMode instance itself. Any other resolved type makes resolveAckMode throw this IllegalArgumentException.
Source
Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/rabbit/RabbitChannelDefinitionProcessor.java:246
throw new IllegalArgumentException("Could not register rabbit listener endpoint on [" +
channelDefinition + "], no " + RabbitAdmin.class.getSimpleName() + " with id '" +
rabbitAdmin + "' was found in the application context", ex);
}
} else {
return null;
}
}
protected AcknowledgeMode resolveAckMode(RabbitInboundChannelModel channelDefinition) {
String ackModeAttr = channelDefinition.getAckMode();
if (StringUtils.hasText(ackModeAttr)) {
Object ackMode = resolveExpression(ackModeAttr);
if (ackMode instanceof String) {
return AcknowledgeMode.valueOf((String) ackMode);
} else if (ackMode instanceof AcknowledgeMode) {
return (AcknowledgeMode) ackMode;
} else {
throw new IllegalArgumentException("ackMode in definition [ " + channelDefinition + " ] must resolve to a String or AcknowledgeMode");
}
} else {
return null;
}
}
protected TaskExecutor resolveExecutor(RabbitInboundChannelModel channelDefinition) {
String executorBeanName = resolve(channelDefinition.getExecutor());
if (StringUtils.hasText(executorBeanName)) {
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve TaskExecutor by bean name");
try {
return this.beanFactory.getBean(executorBeanName, TaskExecutor.class);
} catch (NoSuchBeanDefinitionException ex) {
throw new IllegalArgumentException("Could not register rabbit listener endpoint on [" +
channelDefinition + "], no " + TaskExecutor.class.getSimpleName() + " with id '" +
executorBeanName + "' was found in the application context", ex);
}
} else {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Set ackMode to a valid string enum name: AUTO, MANUAL, or NONE
- Reference an AcknowledgeMode bean directly in the definition
- Fix the expression/placeholder so it resolves to the correct type
- Check the config serialization so ackMode is emitted as a string, not a number/boolean
Example fix
// before "ackMode": true // after "ackMode": "AUTO"
Defensive patterns
Strategy: validation
Validate before calling
Object ack = resolveExpression(channelDefinition.getAckMode());
if (ack != null && !(ack instanceof String) && !(ack instanceof AcknowledgeMode)) {
throw new IllegalArgumentException("ackMode must be a String enum name or AcknowledgeMode");
}
if (ack instanceof String) { AcknowledgeMode.valueOf((String) ack); } // validates enum name early Type guard
boolean isValidAckMode(Object v) {
return v instanceof AcknowledgeMode || (v instanceof String && Arrays.stream(AcknowledgeMode.values()).anyMatch(m -> m.name().equals(v)));
} Try / catch
try {
processor.process(definition);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("ackMode")) {
log.error("Bad ackMode in {}: {}", definition, ex.getMessage());
}
throw ex;
} Prevention
- Store ackMode as a string enum name: AUTO, MANUAL, or NONE
- Ensure config serialization writes ackMode as a string, not boolean/number
- Validate enum fields against allowed values at config load time
When it happens
Trigger: channelDefinition.getAckMode() expression resolves to a non-String/non-AcknowledgeMode object (e.g. Integer, Boolean) while processing the channel definition in createRabbitListenerEndpoint.
Common situations: Config file storing ackMode as a boolean or number; placeholder resolving to the wrong bean; confusion between ack mode names and other frameworks' ackMode types.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- The [<attribute>] must resolve to a String. Resolved to [<cl
- Queues in <channelDefinition> must not be null
- Channel definition <channelDefinition> cannot resolve <resol
- Invalid priority value for <channelDefinition> (must be an i
- Could not register rabbit listener endpoint on [<channelDefi
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/73be483acd63a008.
Report an issue: GitHub.