{"record":{"id":"b5546636d993ba42","repo":"alibaba/spring-ai-alibaba","slug":"there-are-some-empty-fields","errorCode":null,"errorMessage":"There are some empty fields","messagePattern":"There are some empty fields","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/IterationNode.java","lineNumber":433,"sourceCode":"\t\tpublic Converter<ElementInput, ElementOutput> tempStartFlagKey(String tempStartFlagKey) {\n\t\t\tthis.tempStartFlagKey = tempStartFlagKey;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Converter<ElementInput, ElementOutput> tempEndFlagKey(String tempEndFlagKey) {\n\t\t\tthis.tempEndFlagKey = tempEndFlagKey;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Create a complete iteration graph (IterationNode.Start -> SubStateGraphNode -> IterationNode.End ->\n\t\t * TempClear (clear temporary variable values during iteration) -> END) as a subgraph that can be nested by other graphs.\n\t\t */\n\t\tpublic StateGraph convertToStateGraph() throws GraphStateException {\n\t\t\tif (!StringUtils.hasText(this.inputArrayJsonKey) || !StringUtils.hasText(this.outputArrayJsonKey)\n\t\t\t\t\t|| !StringUtils.hasText(this.iteratorItemKey) || !StringUtils.hasText(this.iteratorResultKey)\n\t\t\t\t\t|| this.subGraph == null) {\n\t\t\t\tthrow new IllegalArgumentException(\"There are some empty fields\");\n\t\t\t}\n\t\t\tif (!StringUtils.hasText(this.tempArrayKey)) {\n\t\t\t\tthis.tempArrayKey = \"input_array\";\n\t\t\t}\n\t\t\tif (!StringUtils.hasText(this.tempStartFlagKey)) {\n\t\t\t\tthis.tempStartFlagKey = \"output_start\";\n\t\t\t}\n\t\t\tif (!StringUtils.hasText(this.tempEndFlagKey)) {\n\t\t\t\tthis.tempEndFlagKey = \"output_continue\";\n\t\t\t}\n\t\t\tif (!StringUtils.hasText(this.tempIndexKey)) {\n\t\t\t\tthis.tempIndexKey = \"iteration_index\";\n\t\t\t}\n\t\t\tKeyStrategyFactory strategyFactory = () -> {\n\t\t\t\tMap<String, KeyStrategy> map = new HashMap<>();\n\t\t\t\tmap.put(this.tempArrayKey, new ReplaceStrategy());\n\t\t\t\tmap.put(this.inputArrayJsonKey, new ReplaceStrategy());\n\t\t\t\tmap.put(this.iteratorItemKey, new ReplaceStrategy());","sourceCodeStart":415,"sourceCodeEnd":451,"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/IterationNode.java#L415-L451","documentation":"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.","triggerScenarios":"Calling start().inputArrayJsonKey(...).outputArrayJsonKey(...)...convertToStateGraph() while omitting any of the required setters or leaving subGraph unset via the Builder.","commonSituations":"Copying a builder example and forgetting subGraph(...); dynamic key construction producing empty strings; fluent config built programmatically where a conditional branch skipped a setter.","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."],"exampleFix":"// before\nIterationNode<Object> it = IterationNode.start()\n    .inputArrayJsonKey(\"items\")\n    .outputArrayJsonKey(\"results\")\n    .build();\nStateGraph sg = it.convertToStateGraph(); // throws: iteratorItemKey/ResultKey/subGraph empty\n// after\nIterationNode<Object> it = IterationNode.start()\n    .inputArrayJsonKey(\"items\")\n    .outputArrayJsonKey(\"results\")\n    .iteratorItemKey(\"item\")\n    .iteratorResultKey(\"result\")\n    .subGraph(innerGraph)\n    .build();\nStateGraph sg = it.convertToStateGraph();","handlingStrategy":"validation","validationCode":"void validateIteration(IterationNode.Builder<?> b) {\n    if (b.inputArrayJsonKey == null || b.outputArrayJsonKey == null\n        || b.iteratorItemKey == null || b.iteratorResultKey == null || b.subGraph == null)\n        throw new IllegalStateException(\"Iteration builder incomplete: keys and subGraph required\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    StateGraph sg = iteration.convertToStateGraph();\n} catch (IllegalArgumentException e) {\n    log.error(\"Iteration config incomplete: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["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."],"tags":["iteration-node","builder-validation","missing-configuration"],"backgroundTag":"empty-required-field","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}