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 a Long. Resolved to [<class>] for [<value>]
What it means
resolveExpressionAsLong resolves an attribute expression for a Long-typed setting and accepts null, String-parseable-as-Long, or Number. Any other resolved type causes IllegalStateException. It is called by the retry backoff delay and max configuration, so a bad expression type in backoff settings triggers it.
Solutions
- Ensure the delay/max expression resolves to a whole number or numeric String (e.g. 1000 or "1000").
- Remove units/decimals from the configured value; use milliseconds as a plain integer.
- Fix the backing property type to Long/long if it resolves from a bean field.
- If a Duration is desired, convert to millis in the expression.
Example fix
// before
flowable:
kafka:
retry:
delay: 1.5s # resolves to a Duration, not Long
// after
flowable:
kafka:
retry:
delay: 1500 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 long-like");
Type guard
boolean isLongLike(Object v) { return v == null || v instanceof Number || (v instanceof String s && s.matches("-?\\d+")); } Try / catch
try { ... } catch (IllegalStateException e) { if (e.getMessage().contains("parsed as a Long")) { log.error("Backoff delay/max not a Long: {}", e.getMessage()); } else throw e; } Prevention
- Specify backoff delay/max as plain integer milliseconds
- Avoid Duration-typed properties for these attributes
- Use default fallbacks in placeholders, e.g. ${delay:1000}
When it happens
Trigger: The delay or max attribute of a retry/backoff configuration in the Kafka channel model resolves (via expression/placeholder) to a non-Long, non-String object (e.g. Double or a bean) when the listener endpoint is created.
Common situations: YAML value with decimal point (1.5) where Long expected is fine as String? no—actually a resolved Double; property bound to a Duration object; placeholder pointing to wrong key returning a map/list.
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…
- The [ ] must resolve to an Number or a String that can be…
- topicPattern in channel model
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/8de5d4d9868c691a.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java:477
} 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 + "]");
}
return result;
}
protected Double resolveExpressionAsDouble(String value, String attribute) {
Object resolved = resolveExpression(value);
Double result = null;
if (resolved instanceof String) {
result = Double.parseDouble((String) resolved);
} else if (resolved instanceof Number) {
result = ((Number) resolved).doubleValue();
} else if (resolved != null) {
throw new IllegalStateException(
"The [" + attribute + "] must resolve to an Number or a String that can be parsed as a Double. "
+ "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
}View on GitHub (pinned to d6d39ce1c6)