{"record":{"id":"365029bfd76c6850","repo":"alibaba/spring-ai-alibaba","slug":"subagent-description-is-required","errorCode":null,"errorMessage":"SubAgent description is required","messagePattern":"SubAgent description is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/extension/interceptor/SubAgentSpec.java","lineNumber":156,"sourceCode":"\t\t * Set custom interceptors for this subagent.\n\t\t * These will be applied after the default interceptors from SubAgentInterceptor.\n\t\t */\n\t\tpublic Builder interceptors(List<ModelInterceptor> interceptors) {\n\t\t\tthis.interceptors = interceptors;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Builder enableLoopingLog(boolean enableLoopingLog) {\n\t\t\tthis.enableLoopingLog = enableLoopingLog;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic SubAgentSpec build() {\n\t\t\tif (name == null || name.trim().isEmpty()) {\n\t\t\t\tthrow new IllegalArgumentException(\"SubAgent name is required\");\n\t\t\t}\n\t\t\tif (description == null || description.trim().isEmpty()) {\n\t\t\t\tthrow new IllegalArgumentException(\"SubAgent description is required\");\n\t\t\t}\n\t\t\tif (systemPrompt == null || systemPrompt.trim().isEmpty()) {\n\t\t\t\tthrow new IllegalArgumentException(\"SubAgent system prompt is required\");\n\t\t\t}\n\t\t\treturn new SubAgentSpec(this);\n\t\t}\n\t}\n}\n\n","sourceCodeStart":138,"sourceCodeEnd":166,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/extension/interceptor/SubAgentSpec.java#L138-L166","documentation":"SubAgentSpec's builder validates that the sub-agent has a non-blank description in build(). The description is exposed to the parent (e.g., LLM routing) agent so it can decide when to delegate to this sub-agent; a missing description would make delegation impossible. The check throws IllegalArgumentException when description is null or whitespace-only.","triggerScenarios":"Calling SubAgentSpec.builder()...build() without calling description(String), or passing null/\"\"/blank text to description().","commonSituations":"Writing a minimal test spec and skipping the description; converting legacy agent configs that only carried a name; assuming description is optional because name and systemPrompt are set.","solutions":["Add a meaningful description(...) call before build() so the parent agent can route to this sub-agent.","If the description originates from config/annotations, validate non-blank upstream and surface a clear config error.","Order the builder calls name() -> description() -> systemPrompt() as a habit so none are missed."],"exampleFix":"// before\nSubAgentSpec spec = SubAgentSpec.builder()\n    .name(\"billing-agent\")\n    .systemPrompt(\"You are a billing agent\")\n    .build();\n// after\nSubAgentSpec spec = SubAgentSpec.builder()\n    .name(\"billing-agent\")\n    .description(\"Handles billing and invoice questions\")\n    .systemPrompt(\"You are a billing agent\")\n    .build();","handlingStrategy":"validation","validationCode":"if (description == null || description.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"Cannot build SubAgentSpec: description is required for routing\");\n}","typeGuard":"static boolean hasText(String s) { return s != null && !s.trim().isEmpty(); }","tryCatchPattern":"try {\n    spec = SubAgentSpec.builder()...build();\n} catch (IllegalArgumentException e) {\n    log.error(\"SubAgentSpec missing field: {}\", e.getMessage());\n}","preventionTips":["Write descriptions that help the parent LLM route; never leave them as TODO placeholders.","Validate config-derived descriptions at startup, not at build time.","Use a builder helper that asserts all three required fields."],"tags":["java","builder-validation","subagent"],"backgroundTag":"missing-required-argument","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"}