flowable/flowable-engine · error · IllegalArgumentException
partition in TopicPartition for topic
Error message
partition in TopicPartition for topic '<topic>' can't resolve '<resolvedValue>' as an Integer or String
What it means
Thrown by resolvePartitionAsInteger when a resolved partition value from the channel model is neither an Integer nor a String (nor an Iterable of such). The library only knows how to parse partitions given as integers or numeric strings, so any other resolved type is rejected with this IllegalArgumentException at channel definition processing time.
Solutions
- Ensure the partition attribute resolves to an Integer or a numeric String (e.g. "0-5,10" ranges are handled elsewhere; single values must be Integer or String).
- If using a delegateExpression, make the KafkaPartitionProvider return Integer partitions (convert Long to Integer).
- Check the event payload field referenced by eventField holds a number or numeric string, not an object.
- Wrap the value: return String.valueOf(rawValue) or Integer.valueOf(rawValue.toString()) in your provider.
Example fix
// before
public KafkaPartitionProvider provide() { return ignore -> 3L; } // Long
// after
public KafkaPartitionProvider provide() { return ignore -> 3; } // Integer Defensive patterns
Strategy: validation
Validate before calling
Object v = resolvePartitionValue();
if (!(v instanceof Integer) && !(v instanceof String)) {
throw new IllegalArgumentException("partition value must be Integer or String, got: " + v.getClass());
} Type guard
boolean isValidPartition(Object v) {
return v instanceof Integer || v instanceof String;
} Try / catch
try {
channelRuntimeBuilder.build(channelModel);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("can't resolve")) {
log.error("Bad partition value in channel model", e);
} else { throw e; }
} Prevention
- Always model partition values as Integer or numeric String in event payloads
- Unit-test delegateExpressions supplying partitions to confirm returned types
- Validate channel model JSON against the event-registry schema before deploy
When it happens
Trigger: A TopicPartition 'partition' attribute resolves (via eventField, fixedValue or delegateExpression) to a non-Integer, non-String object such as a Long, a Map, or a POJO that is not Iterable of Integer/String.
Common situations: A delegateExpression returning Long partition numbers, a fixedValue written as a JSON object instead of a number/string, or an event field carrying a non-numeric value.
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
- A channel key detection value is required for the channel…
- At least one of topics, topicPartitions or topicPattern…
- Can only use a collection of String elements for…
- Channel definition cannot resolve as a String[] or a String
- Channel model in tenant has retry configuration but no…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/197ef8e80005e43c.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java:643
.collect(Collectors.toList());
result.addAll(collected);
}
else if (resolvedValue instanceof Integer[]) {
for (Integer partition : (Integer[]) resolvedValue) {
result.add(new TopicPartitionOffset(topic, partition));
}
}
else if (resolvedValue instanceof Integer) {
result.add(new TopicPartitionOffset(topic, (Integer) resolvedValue));
}
else if (resolvedValue instanceof Iterable) {
//noinspection unchecked
for (Object object : (Iterable<Object>) resolvedValue) {
resolvePartitionAsInteger(topic, object, result);
}
}
else {
throw new IllegalArgumentException(
"partition in TopicPartition for topic '" + topic + "' can't resolve '" + resolvedValue + "' as an Integer or String");
}
}
/**
* Parse a list of partitions into a {@link List}. Example: "0-5,10-15".
* This parsing is the same as it is done in the Spring {@code KafkaListenerAnnotationBeanPostProcessor}.
*
* @param partsString the comma-delimited list of partitions/ranges.
* @return the stream of partition numbers, sorted and de-duplicated.
*/
protected Stream<Integer> parsePartitions(String partsString) {
// This is the same as it is done in the Spring KafkaListenerAnnotationBeanPostProcessor#parsePartitions
String[] partsStrings = partsString.split(",");
if (partsStrings.length == 1 && !partsStrings[0].contains("-")) {
return Stream.of(Integer.parseInt(partsStrings[0].trim()));
}
List<Integer> parts = new ArrayList<>();View on GitHub (pinned to d6d39ce1c6)