{"record":{"id":"64895a3a6262b502","repo":"alibaba/spring-ai-alibaba","slug":"chatclient-is-required","errorCode":null,"errorMessage":"ChatClient is required","messagePattern":"ChatClient is required","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/AgentNode.java","lineNumber":74,"sourceCode":"\n\tprivate final RetryTemplate retryTemplate;\n\n\tpublic enum Strategy {\n\n\t\tREACT, TOOL_CALLING\n\n\t}\n\n\tpublic AgentNode(ChatClient chatClient, ToolCallback[] toolCallbacks, Strategy strategy, String systemPrompt,\n\t\t\tString userPrompt, Integer maxIterations, String outputKey) {\n\t\tthis.chatClient = chatClient;\n\t\tthis.strategy = strategy == null ? Strategy.REACT : strategy;\n\t\tthis.systemPrompt = systemPrompt == null ? \"\" : systemPrompt;\n\t\tthis.userPrompt = userPrompt == null ? \"\" : userPrompt;\n\t\tthis.maxIterations = maxIterations == null ? 1 : maxIterations;\n\t\tthis.outputKey = outputKey == null ? \"agent_output\" : outputKey;\n\t\tif (this.chatClient == null) {\n\t\t\tthrow new IllegalArgumentException(\"ChatClient is required\");\n\t\t}\n\n\t\t// Initialize retryTemplate\n\t\tthis.retryTemplate = new RetryTemplate();\n\t\tSimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();\n\t\tretryPolicy.setMaxAttempts(this.maxIterations);\n\t\tthis.retryTemplate.setRetryPolicy(retryPolicy);\n\n\t\t// Initialize toolCallbacks\n\t\tthis.toolCallbacks = Arrays.stream(toolCallbacks).map(toolCallback -> {\n\t\t\t// ToolCalling strategy returns directly after calling the tool, needs to be wrapped to set returnDirect to true\n\t\t\tif (this.strategy == Strategy.TOOL_CALLING && !toolCallback.getToolMetadata().returnDirect()) {\n\t\t\t\tfinal ToolMetadata toolMetadata = ToolMetadata.builder().returnDirect(true).build();\n\t\t\t\treturn new ToolCallback() {\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic ToolDefinition getToolDefinition() {\n\t\t\t\t\t\treturn toolCallback.getToolDefinition();\n\t\t\t\t\t}","sourceCodeStart":56,"sourceCodeEnd":92,"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/AgentNode.java#L56-L92","documentation":"The AgentNode constructor throws this IllegalArgumentException when the chatClient field is null after builder/default initialization. AgentNode delegates all model interaction to a Spring AI ChatClient, so it refuses to construct without one.","triggerScenarios":"Building AgentNode via its builder without calling chatClient(...), or constructing programmatically with a null ChatClient; Spring wiring fails so the injected ChatClient bean is null.","commonSituations":"Omitting the ChatClient in the builder because strategy/prompts were configured; missing spring-ai model starter dependency so no ChatClient bean exists; manually new-ing AgentNode with null in tests.","solutions":["Call .chatClient(chatClient) on the AgentNode builder with a non-null ChatClient","Ensure a ChatClient/ChatModel bean exists (add the appropriate spring-ai starter and model config)","In tests, mock or build a ChatClient explicitly before constructing AgentNode"],"exampleFix":"// before\nAgentNode node = AgentNode.builder().strategy(Strategy.REACT).build();\n// after\nAgentNode node = AgentNode.builder()\n    .strategy(Strategy.REACT)\n    .chatClient(ChatClient.builder(chatModel).build())\n    .build();","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(chatClient, \"AgentNode builder requires a ChatClient\");","typeGuard":"static boolean hasChatClient(AgentNode.Builder b) {\n    return b != null && b.getChatClient() != null;\n}","tryCatchPattern":"try {\n    node = AgentNode.builder().chatClient(cc).build();\n} catch (IllegalArgumentException e) {\n    throw new BeanInitializationException(\"AgentNode misconfigured: \" + e.getMessage(), e);\n}","preventionTips":["Always chain .chatClient(...) in the builder before .build()","Verify the model starter dependency provides a ChatClient/ChatModel bean at startup","Add a smoke test constructing all node beans in the Spring context"],"tags":["constructor-validation","chatclient","null-check","spring-ai"],"backgroundTag":"null-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"}