alibaba/spring-ai-alibaba · error · IllegalArgumentException
Either chatClient or model must be provided
Error message
Either chatClient or model must be provided
What it means
DefaultBuilder.build() requires that at least one of chatClient or model is set; if both are null it throws IllegalArgumentException. A ReactAgent needs an underlying model (directly or through a ChatClient) to run the ReAct loop.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/DefaultBuilder.java:64
public class DefaultBuilder extends Builder {
private static final Logger logger = LoggerFactory.getLogger(DefaultBuilder.class);
public static final String POSSIBLE_LLM_TOOL_NAME_CHANGE_WARNING
= "LLM may have adapted the tool name '{}', especially if the name was truncated due to length limits. If this is the case, you can customize the prefixing and processing logic using McpToolNamePrefixGenerator";
@Override
public ReactAgent build() {
// Validate name is not empty
if (!StringUtils.hasText(this.name)) {
throw new IllegalArgumentException("Agent name must not be empty");
}
// Validate either chatClient or model is provided
if (chatClient == null && model == null) {
throw new IllegalArgumentException("Either chatClient or model must be provided");
}
// Get source options from ChatClient (when provided) or from ChatModel (when building from model).
ChatOptions sourceOptions = (chatClient != null)
? getChatClientDefaultOptions(chatClient)
: getChatModelDefaultOptions(model);
ChatOptions effectiveOptions = mergeSourceOptionsWithAgentOptions(sourceOptions, this.chatOptions);
if (chatClient == null) {
ChatClient.Builder clientBuilder = ChatClient.builder(model,
this.observationRegistry == null ? ObservationRegistry.NOOP : this.observationRegistry,
this.customObservationConvention, this.advisorObservationConvention);
if (effectiveOptions != null) {
clientBuilder.defaultOptions(effectiveOptions);
}
chatClient = clientBuilder.build();
} else {
chatClient = chatClient.mutate().defaultOptions(effectiveOptions).build();View on GitHub (pinned to f82da0b50f)
Solutions
- Add .model(chatModel) (e.g. DashScopeChatModel) to the builder.
- Or add .chatClient(chatClient) built with ChatClient.builder(chatModel).build().
- Ensure the model bean exists: configure the DashScope/OpenAI starter and API key so the ChatModel bean is injected.
- In tests, pass a stub ChatModel implementation.
Example fix
// before
ReactAgent.builder().name("bot").build();
// after
ReactAgent.builder().name("bot").model(chatModel).build(); Defensive patterns
Strategy: validation
Validate before calling
if (chatClient == null && chatModel == null) throw new IllegalArgumentException("Provide either a ChatClient or a ChatModel to the ReactAgent builder"); Try / catch
try { agent = builder.build(); } catch (IllegalArgumentException e) { log.error("Agent '{}': {}", builderName, e.getMessage()); throw e; } Prevention
- Wire the ChatModel bean via the DashScope/OpenAI starter and verify the app context starts.
- In a factory method, require a ChatModel parameter so the compiler enforces presence.
- For tests, provide a stub ChatModel by default.
When it happens
Trigger: Calling ReactAgent.builder().name("x").build() without .model(ChatModel) or .chatClient(ChatClient).
Common situations: Forgetting to wire the ChatModel bean (missing DashScope/OpenAI starter config or API key so the bean is absent), or building agents programmatically in tests without stubbing a model.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- maxParallelTools must be at least 1
- Agent name must not be empty
- Tool not found with id: <id>
- Unknown agent status code:
- Unknown agent type code:
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/477f55a5ecf23986.
Report an issue: GitHub.