alibaba/spring-ai-alibaba · error · IllegalArgumentException

ChatClient is required

Error message

ChatClient is required

What it means

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.

Source

Thrown at spring-boot-starters/spring-ai-alibaba-starter-builtin-nodes/src/main/java/com/alibaba/cloud/ai/graph/node/AgentNode.java:74

	private final RetryTemplate retryTemplate;

	public enum Strategy {

		REACT, TOOL_CALLING

	}

	public AgentNode(ChatClient chatClient, ToolCallback[] toolCallbacks, Strategy strategy, String systemPrompt,
			String userPrompt, Integer maxIterations, String outputKey) {
		this.chatClient = chatClient;
		this.strategy = strategy == null ? Strategy.REACT : strategy;
		this.systemPrompt = systemPrompt == null ? "" : systemPrompt;
		this.userPrompt = userPrompt == null ? "" : userPrompt;
		this.maxIterations = maxIterations == null ? 1 : maxIterations;
		this.outputKey = outputKey == null ? "agent_output" : outputKey;
		if (this.chatClient == null) {
			throw new IllegalArgumentException("ChatClient is required");
		}

		// Initialize retryTemplate
		this.retryTemplate = new RetryTemplate();
		SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
		retryPolicy.setMaxAttempts(this.maxIterations);
		this.retryTemplate.setRetryPolicy(retryPolicy);

		// Initialize toolCallbacks
		this.toolCallbacks = Arrays.stream(toolCallbacks).map(toolCallback -> {
			// ToolCalling strategy returns directly after calling the tool, needs to be wrapped to set returnDirect to true
			if (this.strategy == Strategy.TOOL_CALLING && !toolCallback.getToolMetadata().returnDirect()) {
				final ToolMetadata toolMetadata = ToolMetadata.builder().returnDirect(true).build();
				return new ToolCallback() {
					@Override
					public ToolDefinition getToolDefinition() {
						return toolCallback.getToolDefinition();
					}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Call .chatClient(chatClient) on the AgentNode builder with a non-null ChatClient
  2. Ensure a ChatClient/ChatModel bean exists (add the appropriate spring-ai starter and model config)
  3. In tests, mock or build a ChatClient explicitly before constructing AgentNode

Example fix

// before
AgentNode node = AgentNode.builder().strategy(Strategy.REACT).build();
// after
AgentNode node = AgentNode.builder()
    .strategy(Strategy.REACT)
    .chatClient(ChatClient.builder(chatModel).build())
    .build();
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(chatClient, "AgentNode builder requires a ChatClient");

Type guard

static boolean hasChatClient(AgentNode.Builder b) {
    return b != null && b.getChatClient() != null;
}

Try / catch

try {
    node = AgentNode.builder().chatClient(cc).build();
} catch (IllegalArgumentException e) {
    throw new BeanInitializationException("AgentNode misconfigured: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/64895a3a6262b502. Report an issue: GitHub.