alibaba/spring-ai-alibaba · error · IllegalArgumentException
There are some empty fields
Error message
There are some empty fields
What it means
IterationNode.convertToStateGraph() builds the internal start/clear/end subgraph. Before building it validates that all required keys (inputArrayJsonKey, outputArrayJsonKey, iteratorItemKey, iteratorResultKey) are non-blank and subGraph is non-null, throwing this IllegalArgumentException otherwise. It is a builder-completeness check: the iteration node was not fully configured.
Solutions
- Set every required Builder field: inputArrayJsonKey, outputArrayJsonKey, iteratorItemKey, iteratorResultKey, and subGraph before convertToStateGraph().
- Check which field is blank by logging each StringUtils.hasText result before the call.
- Ensure subGraph is assigned a non-null StateGraph instance.
- Prefer appendToStateGraph over convertToStateGraph if you want defaults applied for temp keys.
Example fix
// before
IterationNode<Object> it = IterationNode.start()
.inputArrayJsonKey("items")
.outputArrayJsonKey("results")
.build();
StateGraph sg = it.convertToStateGraph(); // throws: iteratorItemKey/ResultKey/subGraph empty
// after
IterationNode<Object> it = IterationNode.start()
.inputArrayJsonKey("items")
.outputArrayJsonKey("results")
.iteratorItemKey("item")
.iteratorResultKey("result")
.subGraph(innerGraph)
.build();
StateGraph sg = it.convertToStateGraph(); Defensive patterns
Strategy: validation
Validate before calling
void validateIteration(IterationNode.Builder<?> b) {
if (b.inputArrayJsonKey == null || b.outputArrayJsonKey == null
|| b.iteratorItemKey == null || b.iteratorResultKey == null || b.subGraph == null)
throw new IllegalStateException("Iteration builder incomplete: keys and subGraph required");
} Try / catch
try {
StateGraph sg = iteration.convertToStateGraph();
} catch (IllegalArgumentException e) {
log.error("Iteration config incomplete: {}", e.getMessage());
throw e;
} Prevention
- Set every Builder setter explicitly, never rely on defaults for required keys.
- Centralize key names as constants.
- Add a build-time self-check that logs all configured keys.
- Cover graph construction in a unit test so misconfigurations surface at build time.
When it happens
Trigger: Calling start().inputArrayJsonKey(...).outputArrayJsonKey(...)...convertToStateGraph() while omitting any of the required setters or leaving subGraph unset via the Builder.
Common situations: Copying a builder example and forgetting subGraph(...); dynamic key construction producing empty strings; fluent config built programmatically where a conditional branch skipped a setter.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Agent name must not be empty
- At least one limit must be specified (threadLimit or…
- At least one limit must be specified (threadLimit or…
- ChatModel must be provided for LLM routing agent
- Either chatClient or model must be provided
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/b5546636d993ba42.
Report an issue: GitHub.
Appendix: source
Thrown at spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/IterationNode.java:433
public Converter<ElementInput, ElementOutput> tempStartFlagKey(String tempStartFlagKey) {
this.tempStartFlagKey = tempStartFlagKey;
return this;
}
public Converter<ElementInput, ElementOutput> tempEndFlagKey(String tempEndFlagKey) {
this.tempEndFlagKey = tempEndFlagKey;
return this;
}
/**
* Create a complete iteration graph (IterationNode.Start -> SubStateGraphNode -> IterationNode.End ->
* TempClear (clear temporary variable values during iteration) -> END) as a subgraph that can be nested by other graphs.
*/
public StateGraph convertToStateGraph() throws GraphStateException {
if (!StringUtils.hasText(this.inputArrayJsonKey) || !StringUtils.hasText(this.outputArrayJsonKey)
|| !StringUtils.hasText(this.iteratorItemKey) || !StringUtils.hasText(this.iteratorResultKey)
|| this.subGraph == null) {
throw new IllegalArgumentException("There are some empty fields");
}
if (!StringUtils.hasText(this.tempArrayKey)) {
this.tempArrayKey = "input_array";
}
if (!StringUtils.hasText(this.tempStartFlagKey)) {
this.tempStartFlagKey = "output_start";
}
if (!StringUtils.hasText(this.tempEndFlagKey)) {
this.tempEndFlagKey = "output_continue";
}
if (!StringUtils.hasText(this.tempIndexKey)) {
this.tempIndexKey = "iteration_index";
}
KeyStrategyFactory strategyFactory = () -> {
Map<String, KeyStrategy> map = new HashMap<>();
map.put(this.tempArrayKey, new ReplaceStrategy());
map.put(this.inputArrayJsonKey, new ReplaceStrategy());
map.put(this.iteratorItemKey, new ReplaceStrategy());View on GitHub (pinned to f82da0b50f)