{"record":{"id":"348c2d5ff9009432","repo":"spring-projects/spring-ai","slug":"method-must-not-be-null","errorCode":null,"errorMessage":"Method must not be null","messagePattern":"Method 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/changed/prompt/AbstractMcpPromptListChangedMethodCallback.java","lineNumber":68,"sourceCode":"\t\tAssert.notNull(bean, \"Bean can't be null!\");\n\n\t\tthis.method = method;\n\t\tthis.bean = bean;\n\t\tthis.validateMethod(this.method);\n\t}\n\n\t/**\n\t * Validates that the method signature is compatible with the prompt list changed\n\t * consumer callback.\n\t * <p>\n\t * This method checks that the return type is valid and that the parameters match the\n\t * expected pattern.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the method signature is not compatible\n\t */\n\tprotected void validateMethod(Method method) {\n\t\tif (method == null) {\n\t\t\tthrow new IllegalArgumentException(\"Method must not be null\");\n\t\t}\n\n\t\tthis.validateReturnType(method);\n\t\tthis.validateParameters(method);\n\t}\n\n\t/**\n\t * Validates that the method return type is compatible with the prompt list changed\n\t * consumer callback. This method should be implemented by subclasses to handle\n\t * specific return type validation.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the return type is not compatible\n\t */\n\tprotected abstract void validateReturnType(Method method);\n\n\t/**\n\t * Validates method parameters. This method provides common validation logic.\n\t * @param method The method to validate","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/prompt/AbstractMcpPromptListChangedMethodCallback.java#L50-L86","documentation":"AbstractMcpPromptListChangedMethodCallback.validateMethod rejects a null Method reference before validating the prompt-list-changed handler signature. Registration must pass a concrete reflective Method for the callback to invoke; null indicates a programming error in registration.","triggerScenarios":"Passing null to the constructor/registration API of an McpPromptListChanged callback (e.g. when a reflective method lookup fails silently and null is forwarded).","commonSituations":"Dynamic bean wiring where a Method lookup by name returns null; refactoring renamed the handler method while registration still looked up the old name.","solutions":["Ensure the handler method exists and the reflective lookup returns a non-null Method before constructing the callback","Add an assertion/log at the lookup site so null Methods are caught before registration","Pass a compile-time-safe method reference or a Class+methodName pair verified via getMethod"],"exampleFix":"// before\nMethod m = customLookup(clazz, \"onPromptsChanged\"); // may return null\nnew DefaultMcpPromptListChangedMethodCallback(m);\n// after\nMethod m = Objects.requireNonNull(customLookup(clazz, \"onPromptsChanged\"), \"handler method not found\");\nnew DefaultMcpPromptListChangedMethodCallback(m);","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(method, \"Prompt list changed handler method must not be null\");","typeGuard":"if (method == null) { throw new IllegalArgumentException(\"handler method missing\"); }","tryCatchPattern":"try { registerListChangedCallback(handler); } catch (IllegalArgumentException e) { log.error(\"Bad handler registration: \" + e.getMessage()); }","preventionTips":["Use compile-time method references instead of string-based reflective lookup","Assert non-null Method before constructing callbacks","Cover handler registration in unit tests so renames break tests, not runtime"],"tags":["mcp","reflection","null-argument","validation"],"backgroundTag":"null-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}