spring-projects/spring-ai · error · IllegalArgumentException
Notification must not be null
Error message
Notification must not be null
What it means
SyncMcpLoggingMethodCallback.accept() requires a non-null LoggingMessageNotification before dispatching to the annotated consumer method. Passing null throws IllegalArgumentException immediately. The framework itself always passes a real notification, so this usually indicates direct programmatic use of the callback with a null argument.
Solutions
- Construct a valid LoggingMessageNotification before calling accept().
- Guard the call site: only invoke accept() when the notification is non-null.
- In custom transports, drop or log null notifications instead of forwarding them.
- In tests, use a builder/factory for a sample notification rather than passing null.
Example fix
// before
loggingCallback.accept(notification); // notification may be null
// after
if (notification != null) {
loggingCallback.accept(notification);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (notification == null) { logger.warn("skipping null logging notification"); return; } Type guard
static boolean isUsable(LoggingMessageNotification n) {
return n != null;
} Try / catch
try {
callback.accept(notification);
} catch (IllegalArgumentException e) {
logger.warn("Rejected notification: {}", e.getMessage());
} Prevention
- Never call accept(null); construct a real notification in tests
- Filter null events in custom transports before dispatching
- Prefer Optional<LoggingMessageNotification> at notification sources
When it happens
Trigger: Invoking callback.accept(null) directly in a unit test or custom transport wiring; a custom notification source that forwards null notifications into the consumer; calling the consumer Function-style with an unset variable.
Common situations: Unit tests exercising the callback without building a LoggingMessageNotification; custom MCP transport implementations that don't filter null upstream events; Optional misuse where Optional.empty() was unwrapped to null via .get()-style patterns.
Related errors
- Bean must not be null
- Bean must not be null
- clients must not be empty
- clients must not be empty
- clients must not be empty
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/f4d1eee9acd4afef.
Report an issue: GitHub.
Appendix: source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/logging/SyncMcpLoggingMethodCallback.java:55
implements Consumer<LoggingMessageNotification> {
private SyncMcpLoggingMethodCallback(Builder builder) {
super(builder.method, builder.bean);
}
/**
* Accept the logging message notification and process it.
* <p>
* This method builds the arguments for the method call and invokes the method.
* @param notification The logging message notification, must not be null
* @throws McpLoggingConsumerMethodException if there is an error invoking the logging
* consumer method
* @throws IllegalArgumentException if the notification is null
*/
@Override
public void accept(LoggingMessageNotification notification) {
if (notification == null) {
throw new IllegalArgumentException("Notification must not be null");
}
try {
// Build arguments for the method call
Object[] args = this.buildArgs(this.method, null, notification);
// Invoke the method
this.method.setAccessible(true);
this.method.invoke(this.bean, args);
}
catch (Exception e) {
throw new McpLoggingConsumerMethodException(
"Error invoking logging consumer method: " + this.method.getName(), e);
}
}
/**
* Validates that the method return type is compatible with the logging consumerView on GitHub (pinned to 98a7beda4f)