{"record":{"id":"2463f91f635a4383","repo":"spring-projects/spring-ai","slug":"method-must-not-be-null-2463f9","errorCode":null,"errorMessage":"Method must not be null","messagePattern":"Method must not be null","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/AbstractMcpPromptMethodCallback.java","lineNumber":81,"sourceCode":"\t * @param method The method to create a callback for\n\t * @param bean The bean instance that contains the method\n\t * @param prompt The prompt\n\t */\n\tprotected AbstractMcpPromptMethodCallback(Method method, Object bean, Prompt prompt) {\n\t\tthis.method = method;\n\t\tthis.bean = bean;\n\t\tthis.prompt = prompt;\n\t\tthis.validateMethod(this.method);\n\t}\n\n\t/**\n\t * Validates that the method signature is compatible with the prompt callback.\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 callback.\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 * Checks if a parameter type is compatible with the exchange type.\n\t * @param paramType The parameter type to check\n\t * @return true if the parameter type is compatible with the exchange type, false\n\t * otherwise","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/AbstractMcpPromptMethodCallback.java#L63-L99","documentation":"AbstractMcpPromptMethodCallback.validateMethod() checks that the Method resolved for an @McpPrompt-annotated callback is non-null before validating its return type and parameters. A null Method means the callback was built without a target method, which cannot be invoked reflectively, so construction fails fast with IllegalArgumentException.","triggerScenarios":"Calling AbstractMcpPromptMethodCallback's constructor (directly or via a Builder.build()) with method = null, e.g. a builder whose method field was never set or was resolved to null by a method-lookup helper.","commonSituations":"Reflection-based lookup that fails silently and returns null instead of throwing; custom builder usage forgetting the .method(...) call; annotation scanning code passing through a null from getDeclaredMethod on a missing method name.","solutions":["Ensure the Builder's method(...) is called with a non-null java.lang.reflect.Method before building the callback.","Fix the method-lookup code to throw when the annotated method cannot be found rather than returning null.","Validate the resolved Method for null before passing it into the callback constructor."],"exampleFix":"// before\nMethod m = clazz.getDeclaredMethod(\"promptHandler\"); // throws if absent, or lookup returns null\ncallback = MyPromptCallback.builder().method(maybeNull).bean(bean).build();\n// after\nObjects.requireNonNull(m, \"Resolved @McpPrompt method must not be null\");\ncallback = MyPromptCallback.builder().method(m).bean(bean).build();","handlingStrategy":"validation","validationCode":"Method m = lookupPromptMethod(bean);\nObjects.requireNonNull(m, \"@McpPrompt method must not be null\");","typeGuard":"Optional<Method> findMethod(Class<?> c, String name) { return Arrays.stream(c.getDeclaredMethods()).filter(m -> m.getName().equals(name)).findFirst(); }","tryCatchPattern":"try { callback = builder().method(m).bean(bean).build(); } catch (IllegalArgumentException e) { log.error(\"Callback construction failed: {}\", e.getMessage()); }","preventionTips":["Always call .method(...) on the builder before build()","Make method lookups throw NoSuchMethodException instead of returning null","Resolve Methods once at startup and fail fast on missing annotated methods"],"tags":["java","mcp","null-check","reflection"],"backgroundTag":"null-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}