flowable/flowable-engine · error · IllegalStateException
The [<attribute>] must resolve to a String. Resolved to [<cl
Error message
The [<attribute>] must resolve to a String. Resolved to [<class>] for [<value>]
What it means
RabbitChannelDefinitionProcessor resolves expression/string properties of a Rabbit inbound channel definition into endpoint attributes. resolveExpressionAsStringOrInteger only accepts values that resolve to a String or Integer; anything else (e.g. Boolean, Map, bean) triggers this IllegalStateException naming the offending attribute.
Source
Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/rabbit/RabbitChannelDefinitionProcessor.java:167
if (channelDefinition.getOutboundEventChannelAdapter() == null && StringUtils.hasText(routingKey)) {
String resolvedRoutingKey = resolve(routingKey);
String exchange = resolve(channelDefinition.getExchange());
channelDefinition
.setOutboundEventChannelAdapter(new RabbitOperationsOutboundEventChannelAdapter(rabbitOperations, exchange, resolvedRoutingKey));
}
}
protected String resolveExpressionAsStringOrInteger(String value, String attribute) {
if (!StringUtils.hasLength(value)) {
return null;
}
Object resolved = resolveExpression(value);
if (resolved instanceof String) {
return (String) resolved;
} else if (resolved instanceof Integer) {
return resolved.toString();
} else {
throw new IllegalStateException("The [" + attribute + "] must resolve to a String. "
+ "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
}
}
protected String[] resolveQueues(RabbitInboundChannelModel channelDefinition) {
Collection<String> queues = channelDefinition.getQueues();
if (queues == null) {
throw new IllegalArgumentException("Queues in " + channelDefinition + " must not be null");
}
List<String> resultQueues = new ArrayList<>();
for (String queue : queues) {
resolveQueues(resolveExpression(queue), resultQueues, channelDefinition);
}
return resultQueues.toArray(new String[0]);
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Fix the expression so it resolves to a String (or Integer, which is converted automatically)
- Wrap the resolved value: use toString()-style coercion or String.valueOf in the expression
- Inspect the resolved class name printed in the message to identify the wrong type
- Correct the channel definition XML/JSON so the field is a string literal or resolves to one
Example fix
// before (channel definition)
"concurrency": "${kafka.listener.concurrency}" // resolves to Integer object bean
// after
"concurrency": "${kafka.listener.concurrencyString}" Defensive patterns
Strategy: validation
Validate before calling
Object resolved = resolveExpression(value);
if (!(resolved instanceof String) && !(resolved instanceof Integer)) {
throw new IllegalArgumentException("Attribute " + attribute + " must resolve to String/Integer, got " + resolved.getClass());
} Type guard
boolean isStringResolvable(Object v) {
return v instanceof String || v instanceof Integer;
} Try / catch
try {
String concurrency = processor.resolveExpressionAsStringOrInteger(raw, "concurrency");
} catch (IllegalStateException ex) {
log.error("Channel attribute type wrong: {}", ex.getMessage());
} Prevention
- Keep string-typed channel attributes as string literals or placeholders resolving to strings
- Unit-test SpEL expressions against expected result types
- Avoid reusing typed beans (Boolean, Map) in string attribute positions
When it happens
Trigger: A channel definition attribute (e.g. 'concurrency', 'priority', or another string-typed property) is defined as an expression or property placeholder that resolves to a non-String/non-Integer object, such as a Boolean or a Collection bean.
Common situations: SpEL expression referencing the wrong bean or field type; YAML/JSON channel definition with a boolean or list where a string is expected; placeholder resolving to an unexpected type after refactoring.
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
- Channel definition <channelDefinition> cannot resolve <resol
- Queues in <channelDefinition> must not be null
- Invalid priority value for <channelDefinition> (must be an i
- Could not register rabbit listener endpoint on [<channelDefi
- ackMode in definition [ <channelDefinition> ] must resolve t
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e238e8d8ec8f22fb.
Report an issue: GitHub.