{"record":{"id":"d63f857f095a9170","repo":"alibaba/spring-ai-alibaba","slug":"cannot-append-to-non-list-value-for-key-item-tar","errorCode":null,"errorMessage":"Cannot append to non-list value for key: {item.targetKey()}","messagePattern":"Cannot append to non-list value for key: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/AssignerNode.java","lineNumber":102,"sourceCode":"\t\t\t\t\t\tList<Object> newList = new ArrayList<>((List<?>) targetValue);\n\t\t\t\t\t\tif (value instanceof Collection<?> col) {\n\t\t\t\t\t\t\tnewList.addAll(col);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tnewList.add(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyield newList;\n\t\t\t\t\t}\n\t\t\t\t\telse if (value != null) {\n\t\t\t\t\t\tif (value instanceof Collection<?> col) {\n\t\t\t\t\t\t\tyield new ArrayList<>(col);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tyield new ArrayList<>(List.of(value));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\t\"Cannot append to non-list value for key: \" + item.targetKey());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase CLEAR -> {\n\t\t\t\t\tif (targetValue instanceof List) {\n\t\t\t\t\t\tyield new ArrayList<>();\n\t\t\t\t\t}\n\t\t\t\t\telse if (targetValue instanceof Map) {\n\t\t\t\t\t\tyield new HashMap<>();\n\t\t\t\t\t}\n\t\t\t\t\telse if (targetValue instanceof String) {\n\t\t\t\t\t\tyield \"\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (targetValue instanceof Number) {\n\t\t\t\t\t\tyield 0;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tyield null;","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/AssignerNode.java#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nAssignerNode.Item.builder().targetKey(\"history\").writeMode(WriteMode.APPEND) // history holds a String\n// after\n// initialize history as a list first, or:\nAssignerNode.Item.builder().targetKey(\"history\").writeMode(WriteMode.OVERWRITE)","handlingStrategy":"type-guard","validationCode":"Object cur = state.value(targetKey).orElse(null);\nif (writeMode == WriteMode.APPEND && cur != null && !(cur instanceof List)) {\n    throw new IllegalStateException(targetKey + \" must hold a List for APPEND\");\n}","typeGuard":"static boolean isAppendable(Map<String,Object> state, String key) {\n    Object v = state.get(key);\n    return v == null || v instanceof List;\n}","tryCatchPattern":"try {\n    state = assignerNode.apply(state);\n} catch (IllegalArgumentException e) {\n    logger.error(\"Assigner append failed: {}\", e.getMessage());\n    state.put(targetKey, new ArrayList<>(List.of(newValue)));\n}","preventionTips":["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"],"tags":["assigner","state-management","append","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}