spring-projects/spring-ai · error · IllegalArgumentException
Updated tools list must not be null
Error message
Updated tools list must not be null
What it means
SyncMcpToolListChangedMethodCallback.accept implements the Consumer<List<McpSchema.Tool>> invoked when a client's tool list changes. A null updatedTools list cannot be dispatched to the user handler (the library guarantees a real list), so it throws IllegalArgumentException immediately with 'Updated tools list must not be null'.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/tool/SyncMcpToolListChangedMethodCallback.java:55
implements Consumer<List<McpSchema.Tool>> {
private SyncMcpToolListChangedMethodCallback(Builder builder) {
super(builder.method, builder.bean);
}
/**
* Accept the tool list change notification and process it.
* <p>
* This method builds the arguments for the method call and invokes the method.
* @param updatedTools The updated list of tools, must not be null
* @throws McpToolListChangedConsumerMethodException if there is an error invoking the
* tool list changed consumer method
* @throws IllegalArgumentException if the updatedTools is null
*/
@Override
public void accept(List<McpSchema.Tool> updatedTools) {
if (updatedTools == null) {
throw new IllegalArgumentException("Updated tools list must not be null");
}
try {
// Build arguments for the method call
Object[] args = this.buildArgs(this.method, null, updatedTools);
// Invoke the method
this.method.setAccessible(true);
this.method.invoke(this.bean, args);
}
catch (Exception e) {
throw new McpToolListChangedConsumerMethodException(
"Error invoking tool list changed consumer method: " + this.method.getName(), e);
}
}
/**
* Validates that the method return type is compatible with the tool list changedView on GitHub (pinned to 98a7beda4f)
Solutions
- Never call accept(null); pass the actual list from the client, using List.of() (empty list) when there are no tools
- Add a caller-side null/empty check before invoking the consumer and substitute an empty list for null
- In test setups, use an empty List<McpSchema.Tool> instead of null to simulate 'no tools'
Example fix
// before
callback.accept(null); // throws IllegalArgumentException
// after
java.util.List<io.modelcontextprotocol.spec.McpSchema.Tool> tools =
(raw == null) ? java.util.List.of() : raw;
callback.accept(tools); Defensive patterns
Strategy: validation
Validate before calling
java.util.List<io.modelcontextprotocol.spec.McpSchema.Tool> safeTools = java.util.Objects.requireNonNullElse(updatedTools, java.util.List.of());
Type guard
static java.util.List<io.modelcontextprotocol.spec.McpSchema.Tool> nonNullTools(java.util.List<io.modelcontextprotocol.spec.McpSchema.Tool> l) { return l == null ? java.util.List.of() : l; } Try / catch
try { callback.accept(updatedTools); } catch (IllegalArgumentException e) { log.error("Tool list callback rejected input: {}", e.getMessage()); } Prevention
- Pass the client-provided list directly rather than recomputing it from nullable sources
- Use List.of() to represent 'no tools' instead of null
- In tests, simulate empty tool lists with an empty list, not null
When it happens
Trigger: Invoking accept(null) — typically when custom plumbing or a test feeds the consumer directly, or when a wrapper/adapter constructs the updated-tools list from a nullable source instead of the client's tool list.
Common situations: Unit tests calling the callback with null to check behavior, custom event bridges forwarding a null payload from another notification source, or misconfigured clients that emit change events without computing the new tool list.
Related errors
- Method must not be null
- Bean must not be null
- Bean must not be null
- Method must have exactly 1 parameter (List<McpSchema.Resourc
- Bean must not be null
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/3dffd052f3c39fc7.
Report an issue: GitHub.