alibaba/spring-ai-alibaba · error · IllegalArgumentException
Either 'instruction' or 'includeContents' must be set for Ag
Error message
Either 'instruction' or 'includeContents' must be set for Agent.
What it means
AgentLlmNode.apply() builds the message list for the LLM call. If the graph state has no "messages" key and also no "input" key, there is nothing to send to the model, so it throws IllegalArgumentException telling you to configure an instruction or include contents.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/node/AgentLlmNode.java:169
// Check and manage iteration counter
final AtomicInteger iterations;
if (!config.context().containsKey(MODEL_ITERATION_KEY)) {
iterations = new AtomicInteger(0);
config.context().put(MODEL_ITERATION_KEY, iterations);
} else {
iterations = (AtomicInteger) config.context().get(MODEL_ITERATION_KEY);
iterations.incrementAndGet();
}
// Check and manage messages
List<Message> messages = new ArrayList<>();
if (state.value("messages").isEmpty()) {
// try with "input" key, which is more commonly used in graph input when agent is used as a node.
if (state.value("input").isPresent()) {
messages.add(new UserMessage(state.value("input").get().toString()));
} else {
throw new IllegalArgumentException("Either 'instruction' or 'includeContents' must be set for Agent.");
}
} else {
messages = (List<Message>) state.value("messages").get();
}
augmentUserMessage(messages, outputSchema);
renderTemplatedUserMessage(messages, state.data(), config.metadata());
// Create ModelRequest; include state in context so interceptors (e.g. handoffs step-config) can read it
Map<String, Object> contextMap = new HashMap<>(state.data());
Map<String, Object> metadata = config.metadata().orElse(new HashMap<>());
if (!metadata.isEmpty()) {
contextMap.putAll(metadata);
}
ModelRequest.Builder requestBuilder = ModelRequest.builder()
.messages(messages)
.options(this.chatOptions != null ? this.chatOptions.copy() : null)
.context(contextMap);View on GitHub (pinned to f82da0b50f)
Solutions
- Set an instruction on the Agent builder so the node has a prompt
- Include contents / seed the state with at least one Message
- Pass input under the "input" key when using the agent as a plain graph node
- Pass input as {"messages": [new UserMessage("...")]} to match the expected state key
Example fix
// before
OverAllState input = new OverAllState(Map.of("query", "hello")); // no 'messages'/'input'
// after
OverAllState input = new OverAllState(Map.of("input", "hello"));
// or: Map.of("messages", List.of(new UserMessage("hello"))) Defensive patterns
Strategy: try-catch
Validate before calling
boolean agentInputValid(Map<String,Object> state) { return state.containsKey("messages") || state.containsKey("input"); } Type guard
boolean hasMessages(OverAllState s) { return s.value("messages").isPresent() || s.value("input").isPresent(); } Try / catch
try { node.apply(state); } catch (IllegalArgumentException e) { log.error("Agent received no messages/input: {}", state.data()); throw e; } Prevention
- Always set an instruction on the Agent builder
- When using the agent as a graph node, pass input under the "input" or "messages" key
- Normalize upstream node outputs to the "messages" key
When it happens
Trigger: Invoking an agent (or graph using AgentLlmNode as a node) whose input state contains neither "messages" nor "input", e.g. passing an empty map or only non-message keys like "input_schema".
Common situations: Feeding a graph with structured input (JSON fields) instead of chat messages; forgetting to set the agent's instruction/prompt in the builder; upstream node failed to produce "messages"; renaming the input key in a custom node.
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
- Tool call limits exceeded: ${threadCount}/${threadLimit} thr
- ${message.getText()}
- Last message is neither an AssistantMessage nor a ToolRespon
- Cannot find AssistantMessage before ToolResponseMessage
- Message before ToolResponseMessage is not an AssistantMessag
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/ab703a836952e426.
Report an issue: GitHub.