{"record":{"id":"c6ff5724a117ed49","repo":"spring-projects/spring-ai","slug":"bean-must-not-be-null","errorCode":null,"errorMessage":"Bean must not be null","messagePattern":"Bean 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":211,"sourceCode":"\t\t * @param promptListChanged The prompt list changed annotation\n\t\t * @return This builder\n\t\t */\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tpublic T promptListChanged(McpPromptListChanged promptListChanged) {\n\t\t\t// No additional configuration needed from the annotation at this time\n\t\t\treturn (T) this;\n\t\t}\n\n\t\t/**\n\t\t * Validate the builder state.\n\t\t * @throws IllegalArgumentException if the builder state is invalid\n\t\t */\n\t\tprotected void validate() {\n\t\t\tif (this.method == null) {\n\t\t\t\tthrow new IllegalArgumentException(\"Method must not be null\");\n\t\t\t}\n\t\t\tif (this.bean == null) {\n\t\t\t\tthrow new IllegalArgumentException(\"Bean must not be null\");\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Build the callback.\n\t\t * @return A new callback instance\n\t\t */\n\t\tpublic abstract R build();\n\n\t}\n\n}\n","sourceCodeStart":193,"sourceCodeEnd":224,"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#L193-L224","documentation":"Thrown by AbstractMcpPromptListChangedMethodCallback.Builder.validate() when the builder's `bean` field is null at build time. The callback invokes the handler method on this bean instance (this.method.invoke(this.bean, args)); without a target instance there is no receiver for the reflective call. Validation runs eagerly in build() to fail fast on misconfiguration.","triggerScenarios":"Calling build() without calling bean(Object) (or the bean field not being set by the constructor path used). Occurs when wiring the callback manually and forgetting to supply the handler instance, or when dependency injection produced a null bean.","commonSituations":"Manual builder wiring in tests; the annotated handler bean not being registered in the Spring context so injection yields null; constructing the builder from code where the handler instance is resolved conditionally and can be null.","solutions":["Call bean(Object) on the builder with the instance that declares the prompt-list-changed handler method before build().","Ensure the handler class is a registered Spring bean (@Component or @Bean definition) so the framework can inject a non-null instance.","Add a startup assertion/bean-exists check if the handler bean is resolved dynamically."],"exampleFix":"// before\nAsyncMcpPromptListChangedMethodCallback.builder()\n    .method(handlerMethod)\n    .build(); // bean == null\n// after\nAsyncMcpPromptListChangedMethodCallback.builder()\n    .method(handlerMethod)\n    .bean(myPromptHandler)\n    .build();","handlingStrategy":"validation","validationCode":"if (handlerBean == null) {\n    throw new IllegalStateException(\"handler bean not injected — check Spring registration\");\n}\nAsyncMcpPromptListChangedMethodCallback.builder().bean(handlerBean).method(handler).build();","typeGuard":null,"tryCatchPattern":"try {\n    callback = builder.build();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Bean must not be null\")) {\n        throw new ConfigurationException(\"Builder missing bean(Object) — supply the handler instance\", e);\n    }\n    throw e;\n}","preventionTips":["Register the handler as a Spring bean so injection never yields null.","Set bean(...) immediately after method(...) in builder chains.","Fail fast in @PostConstruct if the handler bean is null."],"tags":["mcp","builder-validation","null-bean"],"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"}