alibaba/spring-ai-alibaba · error · IllegalArgumentException
Cannot append to non-list value for key: {item.targetKey()}
Error message
Cannot append to non-list value for key: {item.targetKey()} What it means
AssignerNode.apply throws this IllegalArgumentException when a write item uses the APPEND write mode but the current state value at targetKey exists and is not a List. Append semantics only work on list-valued state keys.
Source
Thrown at spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/AssignerNode.java:102
List<Object> newList = new ArrayList<>((List<?>) targetValue);
if (value instanceof Collection<?> col) {
newList.addAll(col);
}
else {
newList.add(value);
}
yield newList;
}
else if (value != null) {
if (value instanceof Collection<?> col) {
yield new ArrayList<>(col);
}
else {
yield new ArrayList<>(List.of(value));
}
}
else {
throw new IllegalArgumentException(
"Cannot append to non-list value for key: " + item.targetKey());
}
}
case CLEAR -> {
if (targetValue instanceof List) {
yield new ArrayList<>();
}
else if (targetValue instanceof Map) {
yield new HashMap<>();
}
else if (targetValue instanceof String) {
yield "";
}
else if (targetValue instanceof Number) {
yield 0;
}
else {
yield null;View on GitHub (pinned to f82da0b50f)
Solutions
- Ensure the target key is initialized as a List (or absent) before APPEND runs
- Change the rule's writeMode to OVERWRITE if replacing the scalar is intended
- Add a preceding AssignerNode step that sets the key to an empty list
Example fix
// before
AssignerNode.Item.builder().targetKey("history").writeMode(WriteMode.APPEND) // history holds a String
// after
// initialize history as a list first, or:
AssignerNode.Item.builder().targetKey("history").writeMode(WriteMode.OVERWRITE) Defensive patterns
Strategy: type-guard
Validate before calling
Object cur = state.value(targetKey).orElse(null);
if (writeMode == WriteMode.APPEND && cur != null && !(cur instanceof List)) {
throw new IllegalStateException(targetKey + " must hold a List for APPEND");
} Type guard
static boolean isAppendable(Map<String,Object> state, String key) {
Object v = state.get(key);
return v == null || v instanceof List;
} Try / catch
try {
state = assignerNode.apply(state);
} catch (IllegalArgumentException e) {
logger.error("Assigner append failed: {}", e.getMessage());
state.put(targetKey, new ArrayList<>(List.of(newValue)));
} Prevention
- Initialize list-typed state keys with an empty list before APPEND rules run
- Document the expected type of every state key in the workflow schema
- Prefer OVERWRITE for scalar keys and APPEND only for explicitly list keys
When it happens
Trigger: An assigner rule with writeMode=APPEND targets a key whose existing state value is a String, Map, or other non-List object, so the switch in apply cannot merge the new value.
Common situations: Key initialized elsewhere as a scalar (e.g. set by another node to a String) then targeted by APPEND; first write used OVERWRITE with a non-list value and a later APPEND hits it; state schema changed between workflow versions.
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
- unknown component type: + componentType.getValue()
- extra tool param should be map
- INVALID_PARAMS
- WORKFLOW_CONFIG_INVALID
- Invalid write mode: ${dslValue}
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/d63f857f095a9170.
Report an issue: GitHub.