spring-projects/spring-ai · error · IllegalArgumentException
Updated resources list must not be null
Error message
Updated resources list must not be null
What it means
SyncMcpResourceListChangedMethodCallback.accept(List<McpSchema.Resource>) rejects a null updatedResources list with IllegalArgumentException before invoking the consumer method. The library treats null as an invalid notification payload rather than an empty change set.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/resource/SyncMcpResourceListChangedMethodCallback.java:56
implements Consumer<List<McpSchema.Resource>> {
private SyncMcpResourceListChangedMethodCallback(Builder builder) {
super(builder.method, builder.bean);
}
/**
* Accept the resource list change notification and process it.
* <p>
* This method builds the arguments for the method call and invokes the method.
* @param updatedResources The updated list of resources, must not be null
* @throws McpResourceListChangedConsumerMethodException if there is an error invoking
* the resource list changed consumer method
* @throws IllegalArgumentException if the updatedResources is null
*/
@Override
public void accept(List<McpSchema.Resource> updatedResources) {
if (updatedResources == null) {
throw new IllegalArgumentException("Updated resources list must not be null");
}
try {
// Build arguments for the method call
Object[] args = this.buildArgs(this.method, null, updatedResources);
// Invoke the method
this.method.setAccessible(true);
this.method.invoke(this.bean, args);
}
catch (Exception e) {
throw new McpResourceListChangedConsumerMethodException(
"Error invoking resource list changed consumer method: " + this.method.getName(), e);
}
}
/**
* Validates that the method return type is compatible with the resource list changedView on GitHub (pinned to 98a7beda4f)
Solutions
- Pass an empty List (List.of() / Collections.emptyList()) instead of null when no resources exist.
- Null-check the notification payload before invoking accept().
- If this comes from a custom transport, normalize null lists to empty lists at the transport layer.
Example fix
// before callback.accept(null); // after callback.accept(updatedResources == null ? List.of() : updatedResources);
Defensive patterns
Strategy: validation
Validate before calling
if (updatedResources == null) { updatedResources = List.of(); } Type guard
static List<McpSchema.Resource> orEmpty(List<McpSchema.Resource> l) {
return l == null ? List.of() : l;
} Try / catch
try {
callback.accept(updatedResources);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Updated resources list must not be null")) {
log.warn("Received null resources payload; treating as empty");
}
throw e;
} Prevention
- Normalize null lists to empty lists at the transport/notification layer.
- Never pass null where the API documents List<McpSchema.Resource>.
When it happens
Trigger: Calling accept(null) directly, or a server/notification path delivering a resource-list-changed event with a null resources list into a sync callback.
Common situations: Custom or test harness code simulating resource change notifications and passing null instead of an empty list.
Related errors
- Bean must not be null
- Bean must not be null
- Prefix or toolName cannot be null or empty
- Method must have exactly 1 parameter (List<McpSchema.Resourc
- Parameter must be of type List<McpSchema.Resource>:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/95e7a151fec8f0ba.
Report an issue: GitHub.