flowable/flowable-engine · error · IllegalStateException
The [ ] must resolve to an Number or a String that can be…
Error message
The [<attribute>] must resolve to an Number or a String that can be parsed as an Integer. Resolved to [<class>] for [<value>]
What it means
resolveExpressionAsInteger resolves a channel-model attribute expression (e.g. a SpEL/placeholder) and expects null, a Number, or a String parseable as Integer. If the resolved value is any other type (e.g. Boolean, Map, bean), IllegalStateException is thrown naming the attribute, resolved class, and raw value.
Solutions
- Point the attribute expression at a numeric value or numeric String (e.g. ${kafka.retry.maxAttempts} resolving to "3").
- Check the resolved bean/property type; change it to Integer/int in the configuration class.
- Use Integer.parseInt-safe values: ensure no units like "3s" or thousands separators in the String.
- Cast or convert the expression, e.g. ${...} backed by a conversion service that yields Number.
Example fix
// before (application.yml)
kafka:
retry:
maxAttempts: three # resolves as non-numeric string? or a map
// after
kafka:
retry:
maxAttempts: 3 Defensive patterns
Strategy: type-guard
Validate before calling
Object v = resolveExpression(value); if (v != null && !(v instanceof Number) && !(v instanceof String)) throw new IllegalArgumentException(attribute + " must be numeric");
Type guard
boolean isIntegerLike(Object v) { return v == null || v instanceof Number || (v instanceof String s && s.matches("-?\\d+")); } Try / catch
try { processor.createEndpointConfigurations(...); } catch (IllegalStateException e) { if (e.getMessage().contains("must resolve to")) { log.error("Bad attribute type: {}", e.getMessage()); } else throw e; } Prevention
- Quote numeric literals in channel model YAML/JSON
- Keep retry/attempt attributes as ints in backing config classes
- Test placeholder resolution in a boot-time validation test
When it happens
Trigger: An integer attribute of the Kafka channel model (e.g. a retry-config field like maxAttempts or concurrency) is set via an expression that resolves to a non-numeric object, and resolveExpressionAsInteger (directly or via resolveRetryConfiguration) processes it.
Common situations: Placeholder points to a bean/Map instead of a property; YAML property typed as list/boolean; expression typo resolving a method result of wrong type; property missing type coercion in a custom resolver.
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
- The [ ] must resolve to a Boolean or a String that can be…
- The [ ] must resolve to a String. Resolved to [ ] for [ ]
- The [ ] must resolve to an Number or a String that can be…
- topicPattern in channel model
- At least one of topics, topicPartitions or topicPattern…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7d7b91d4acd7e0ba.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java:462
channelModel.setOutboundEventChannelAdapter(new KafkaOperationsOutboundEventChannelAdapter(
kafkaOperations, partitionProvider, resolvedTopic, messageKeyProvider));
}
}
protected Integer resolveExpressionAsInteger(String value, String attribute) {
return resolveExpressionAsInteger(value, attribute, null);
}
protected Integer resolveExpressionAsInteger(String value, String attribute, Integer defaultValue) {
Object resolved = resolveExpression(value);
Integer result = defaultValue;
if (resolved instanceof String) {
result = Integer.parseInt((String) resolved);
} else if (resolved instanceof Number) {
result = ((Number) resolved).intValue();
} else if (resolved != null) {
throw new IllegalStateException(
"The [" + attribute + "] must resolve to an Number or a String that can be parsed as an Integer. "
+ "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
}
return result;
}
protected Long resolveExpressionAsLong(String value, String attribute) {
Object resolved = resolveExpression(value);
Long result = null;
if (resolved instanceof String) {
result = Long.parseLong((String) resolved);
} else if (resolved instanceof Number) {
result = ((Number) resolved).longValue();
} else if (resolved != null) {
throw new IllegalStateException(
"The [" + attribute + "] must resolve to an Number or a String that can be parsed as a Long. "
+ "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
}View on GitHub (pinned to d6d39ce1c6)