{"record":{"id":"f4d1eee9acd4afef","repo":"spring-projects/spring-ai","slug":"notification-must-not-be-null","errorCode":null,"errorMessage":"Notification must not be null","messagePattern":"Notification must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/logging/SyncMcpLoggingMethodCallback.java","lineNumber":55,"sourceCode":"\t\timplements Consumer<LoggingMessageNotification> {\n\n\tprivate SyncMcpLoggingMethodCallback(Builder builder) {\n\t\tsuper(builder.method, builder.bean);\n\t}\n\n\t/**\n\t * Accept the logging message notification and process it.\n\t * <p>\n\t * This method builds the arguments for the method call and invokes the method.\n\t * @param notification The logging message notification, must not be null\n\t * @throws McpLoggingConsumerMethodException if there is an error invoking the logging\n\t * consumer method\n\t * @throws IllegalArgumentException if the notification is null\n\t */\n\t@Override\n\tpublic void accept(LoggingMessageNotification notification) {\n\t\tif (notification == null) {\n\t\t\tthrow new IllegalArgumentException(\"Notification must not be null\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Build arguments for the method call\n\t\t\tObject[] args = this.buildArgs(this.method, null, notification);\n\n\t\t\t// Invoke the method\n\t\t\tthis.method.setAccessible(true);\n\t\t\tthis.method.invoke(this.bean, args);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new McpLoggingConsumerMethodException(\n\t\t\t\t\t\"Error invoking logging consumer method: \" + this.method.getName(), e);\n\t\t}\n\t}\n\n\t/**\n\t * Validates that the method return type is compatible with the logging consumer","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/logging/SyncMcpLoggingMethodCallback.java#L37-L73","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nloggingCallback.accept(notification); // notification may be null\n// after\nif (notification != null) {\n    loggingCallback.accept(notification);\n}","handlingStrategy":"type-guard","validationCode":"if (notification == null) { logger.warn(\"skipping null logging notification\"); return; }","typeGuard":"static boolean isUsable(LoggingMessageNotification n) {\n    return n != null;\n}","tryCatchPattern":"try {\n    callback.accept(notification);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"Rejected notification: {}\", e.getMessage());\n}","preventionTips":["Never call accept(null); construct a real notification in tests","Filter null events in custom transports before dispatching","Prefer Optional<LoggingMessageNotification> at notification sources"],"tags":["mcp","null-check","validation","java"],"backgroundTag":"null-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}