{"record":{"id":"27d3b1a7fa7bcd9c","repo":"spring-projects/spring-ai","slug":"bean-must-not-be-null-27d3b1","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/elicitation/AbstractMcpElicitationMethodCallback.java","lineNumber":239,"sourceCode":"\t\t * @param elicitation The elicitation annotation\n\t\t * @return This builder\n\t\t */\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tpublic T elicitation(McpElicitation elicitation) {\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":221,"sourceCodeEnd":252,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/elicitation/AbstractMcpElicitationMethodCallback.java#L221-L252","documentation":"Thrown by Builder.validate() in AbstractMcpElicitationMethodCallback when the target bean (the instance holding the annotated handler method) is null at build() time. The callback invokes method on this bean, so it must be a live instance.","triggerScenarios":"Calling build() on a Sync/AsyncMcpElicitationMethodCallback builder with .method(...) set but no .bean(instance) — e.g. passing a null Spring bean or forgetting the bean call.","commonSituations":"Manual registration where the handler bean is fetched from the application context and the lookup returned null (bean not yet created, wrong name, or @Lazy bean accessed too early).","solutions":["Pass a non-null handler instance with .bean(handlerInstance)","Verify the Spring bean actually exists in the context before registering (context.getBean returns non-null)","Ensure bean initialization order: register elicitation callbacks after the handler bean is constructed"],"exampleFix":"// before\nObject handler = context.getBean(\"elicitationHandler\"); // resolves to null\nbuilder.method(method).bean(handler).build();\n\n// after\nMyHandler handler = context.getBean(MyHandler.class);\nif (handler != null) {\n    builder.method(method).bean(handler).build();\n}\n","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(handlerBean, \"bean must be set before build()\");\nbuilder.method(method).bean(handlerBean).build();","typeGuard":"boolean canRegister(Object handler) { return handler != null; }","tryCatchPattern":null,"preventionTips":["Verify Spring beans exist (context.getBean) before registering their methods as callbacks","Register elicitation callbacks in a phase after handler beans are initialized","Never pass a possibly-null result of getBean directly into the builder"],"tags":["java","mcp","elicitation","builder","null-argument"],"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"}