{"record":{"id":"d20a16f264968625","repo":"spring-projects/spring-ai","slug":"method-must-not-be-null-d20a16","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/complete/AbstractMcpCompleteMethodCallback.java","lineNumber":126,"sourceCode":"\t\t\tthis.uriVariables = this.uriTemplateManager.getVariableNames();\n\t\t}\n\t\telse {\n\t\t\tthis.uriTemplateManager = null;\n\t\t\tthis.uriVariables = new ArrayList<>();\n\t\t}\n\t}\n\n\t/**\n\t * Validates that the method signature is compatible with the complete 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 complete callback.\n\t * This method should be implemented by subclasses to handle specific return type\n\t * 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 and\n\t * delegates exchange type checking to subclasses.","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/AbstractMcpCompleteMethodCallback.java#L108-L144","documentation":"AbstractMcpCompleteMethodCallback.validateMethod() first checks that the Method argument is non-null before validating its return type and parameters. A null Method means the framework could not resolve the annotated method (e.g., wrong method name in configuration or a null passed programmatically), and registration fails immediately with this IllegalArgumentException.","triggerScenarios":"Passing null as the Method to the callback constructor or builder, or programmatic registration where reflection (e.g., Class.getMethod(...)) returned null or the lookup result was not checked.","commonSituations":"Typos in method names used for programmatic registration; refactoring away a method still referenced by name; constructing the callback manually in tests.","solutions":["Pass the actual reflected Method instance of your completion handler to the callback/builder.","Check any reflection lookup result for null before constructing the callback.","Prefer annotation-based registration so the framework resolves the Method itself."],"exampleFix":"// before\nMethod m = bean.getClass().getMethod(\"onComplete\"); // NoSuchMethod risk / unchecked\ncallback = new CallbackImpl(null, bean, ...); // throws\n// after\nMethod m = bean.getClass().getMethod(\"onComplete\", List.class);\nAssert.notNull(m, \"method missing\");\ncallback = new CallbackImpl(m, bean, ...);","handlingStrategy":"validation","validationCode":"if (method == null) throw new IllegalStateException(\"completion method could not be resolved; check registration\");","typeGuard":"boolean hasMethod = (method instanceof java.lang.reflect.Method m) && m.getDeclaringClass().isInstance(bean);\nif (!hasMethod) { /* fix registration before constructing callback */ }","tryCatchPattern":null,"preventionTips":["Verify method names in programmatic registration against the bean class.","Handle NoSuchMethodException explicitly instead of passing a possibly-null Method.","Prefer annotation-based registration over manual Method resolution."],"tags":["mcp","null-check","reflection","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-14T05:17:10.506Z"}