{"record":{"id":"951b3c1ed7e0b85c","repo":"alibaba/spring-ai-alibaba","slug":"sub-agents-must-be-provided","errorCode":null,"errorMessage":"Sub-agents must be provided","messagePattern":"Sub-agents must be provided","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/agent/ParallelAgent.java","lineNumber":203,"sourceCode":"\t\t/**\n\t\t * Sets the merge strategy for combining parallel execution results.\n\t\t * @param mergeStrategy the strategy to use for merging results\n\t\t * @return this builder instance for method chaining\n\t\t */\n\t\tpublic ParallelAgentBuilder mergeStrategy(MergeStrategy mergeStrategy) {\n\t\t\tthis.mergeStrategy = mergeStrategy;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic ParallelAgentBuilder mergeOutputKey(String mergeOutputKey) {\n\t\t\tthis.mergeOutputKey = mergeOutputKey;\n\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic ParallelAgentBuilder subAgents(List<Agent> subAgents) {\n\t\t\tif (subAgents == null || subAgents.isEmpty()) {\n\t\t\t\tthrow new IllegalArgumentException(\"Sub-agents must be provided\");\n\t\t\t}\n\t\t\tif (subAgents.stream().anyMatch(agent -> !(agent instanceof BaseAgent))) {\n\t\t\t\tthrow new IllegalArgumentException(\"Sub-agents must be BaseAgent\");\n\t\t\t}\n\t\t\treturn super.subAgents(subAgents);\n\t\t}\n\n\t\t/**\n\t\t * Sets the maximum number of sub-agents that can execute concurrently.\n\t\t * @param maxConcurrency the maximum concurrency limit\n\t\t * @return this builder instance for method chaining\n\t\t */\n\t\tpublic ParallelAgentBuilder maxConcurrency(Integer maxConcurrency) {\n\t\t\tthis.maxConcurrency = maxConcurrency;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/flow/agent/ParallelAgent.java#L185-L221","documentation":"ParallelAgent's builder validates in subAgents(List) that the list is non-null and non-empty; a parallel agent with nothing to run concurrently is meaningless, so it throws IllegalArgumentException. This is a fail-fast check performed when the builder method is called (and is exercised by the module's tests).","triggerScenarios":"Calling ParallelAgent.builder().subAgents(null), subAgents(List.of()), or subAgents(emptyList).","commonSituations":"Building sub-agent lists dynamically from config where the section is missing/empty; filtering a list down to zero agents before passing it; a wiring bug where the list field was never populated.","solutions":["Ensure at least one sub-agent is created and passed before building the parallel agent.","Check upstream config/bean loading that produced an empty list and fail earlier with a clear message about which config key is empty.","If parallelism is optional in your flow, skip creating the ParallelAgent when the list is empty."],"exampleFix":"// before\nList<Agent> agents = loadSubAgents(); // may return empty\nparallelBuilder.subAgents(agents); // throws: Sub-agents must be provided\n// after\nList<Agent> agents = loadSubAgents();\nif (agents.isEmpty()) {\n    throw new IllegalStateException(\"No sub-agents configured for parallelAgent\");\n}\nparallelBuilder.subAgents(agents);","handlingStrategy":"validation","validationCode":"if (subAgents == null || subAgents.isEmpty()) {\n    throw new IllegalStateException(\"parallelAgent requires at least one sub-agent\");\n}\nparallelBuilder.subAgents(subAgents);","typeGuard":"static boolean hasSubAgents(List<Agent> l) { return l != null && !l.isEmpty(); }","tryCatchPattern":"try {\n    parallelBuilder.subAgents(agents);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Sub-agents must be provided\")) {\n        log.error(\"No sub-agents configured; check agent list source\");\n    }\n}","preventionTips":["Validate config-driven agent lists at startup before building agents.","Filter before passing, but re-check the filtered list is non-empty.","Log the count of sub-agents assembled to catch silently-empty lists."],"tags":["java","parallel-agent","builder-validation","empty-list"],"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-14T05:17:10.506Z"}