flowable/flowable-engine · error · IllegalArgumentException
Channel definition cannot resolve as a String[] or a String
Error message
Channel definition <channelDefinition> cannot resolve <resolvedValue> as a String[] or a String
What it means
resolveTopics resolves the topics attribute of a Kafka inbound channel; the resolved value must be a String, a String[]/array of Strings, or an Iterable containing Strings. Any other resolved type triggers IllegalArgumentException naming the channel definition and the offending value. This validates the multi-topic configuration at endpoint creation time.
Solutions
- Ensure every topic entry is a String, e.g. topics: ["orders", "payments"].
- Fix the placeholder/expression so it resolves to String[] or List<String>.
- If using a Map, flatten to a list of keys (e.g. ${...keys} style) before assigning.
- Quote numeric topic names so they stay Strings.
Example fix
// before topics: [101, 102] // after topics: ["101", "102"]
Defensive patterns
Strategy: validation
Validate before calling
Object resolved = resolveExpression(topicsValue);
boolean ok = resolved instanceof String
|| resolved instanceof String[]
|| (resolved instanceof Iterable<?> it && StreamSupport.stream(it.spliterator(), false).allMatch(o -> o instanceof String));
if (!ok) throw new IllegalArgumentException("topics must resolve to String or String[]/Iterable<String>"); Try / catch
try { ... } catch (IllegalArgumentException e) { if (e.getMessage().contains("as a String[] or a String")) { log.error("Bad topics config: {}", e.getMessage()); } else throw e; } Prevention
- Model topics as a list of quoted strings
- Do not bind topics to Maps or mixed-type collections
- Validate channel model JSON against a schema allowing only strings in topics
When it happens
Trigger: The channel's topics attribute expression resolves to e.g. a List of Integers, a Map, or a single non-String object; resolveTopics recursion hits an element that is neither String, String[], nor Iterable.
Common situations: topics: [1,2,3] numeric list in model; placeholder points to a Map of topic->options; mixed-type array from environment variables.
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
- expected expression to resolve to but it did not. Resolved…
- Model value is not of type boolean, but of type
- Model value should be a String
- Only string variable values are supported for like, but was
- Only string variable values are supported using like, but…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0b6a2c3e09203b74.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java:560
}
return resultTopics;
}
protected void resolveTopics(Object resolvedValue, List<String> result, KafkaInboundChannelModel channelDefinition) {
if (resolvedValue instanceof String[]) {
for (String object : (String[]) resolvedValue) {
resolveTopics(object, result, channelDefinition);
}
} else if (resolvedValue instanceof String) {
result.add((String) resolvedValue);
} else if (resolvedValue instanceof Iterable) {
for (Object object : (Iterable<?>) resolvedValue) {
resolveTopics(object, result, channelDefinition);
}
} else {
throw new IllegalArgumentException(
"Channel definition " + channelDefinition + " cannot resolve " + resolvedValue + " as a String[] or a String");
}
}
protected Pattern resolvePattern(KafkaInboundChannelModel channelModel) {
Pattern pattern = null;
String topicPattern = channelModel.getTopicPattern();
if (StringUtils.hasText(topicPattern)) {
Object resolved = resolveExpression(topicPattern);
if (resolved instanceof String) {
pattern = Pattern.compile((String) resolved);
} else if (resolved instanceof Pattern) {
pattern = (Pattern) resolved;
} else if (resolved != null) {
throw new IllegalStateException(
"topicPattern in channel model [ " + channelModel + " ] must resolve to a Pattern or String, not " + resolved.getClass());
}
}View on GitHub (pinned to d6d39ce1c6)