{"record":{"id":"2afdff1a2229c3d5","repo":"spring-projects/spring-ai","slug":"bean-must-not-be-null-2afdff","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/complete/AbstractMcpCompleteMethodCallback.java","lineNumber":488,"sourceCode":"\t\t * @param uriTemplateManagerFactory The URI template manager factory\n\t\t * @return This builder\n\t\t */\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tpublic T uriTemplateManagerFactory(McpUriTemplateManagerFactory uriTemplateManagerFactory) {\n\t\t\tthis.uriTemplateManagerFactory = uriTemplateManagerFactory;\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\tif ((this.prompt == null || this.prompt.isEmpty()) && (this.uri == null || this.uri.isEmpty())) {\n\t\t\t\tthrow new IllegalArgumentException(\"Either prompt or uri must be provided\");\n\t\t\t}\n\t\t\tif ((this.prompt != null && !this.prompt.isEmpty()) && (this.uri != null && !this.uri.isEmpty())) {\n\t\t\t\tthrow new IllegalArgumentException(\"Only one of prompt or uri can be provided\");\n\t\t\t}\n\t\t\tif (this.uriTemplateManagerFactory == null) {\n\t\t\t\tthis.uriTemplateManagerFactory = new DefaultMcpUriTemplateManagerFactory();\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","sourceCodeStart":470,"sourceCodeEnd":506,"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#L470-L506","documentation":"Builder validation error: the AbstractMcpCompleteMethodCallback builder was built without setting the target bean that owns the completion method. validate() rejects a null bean because the callback needs it to invoke the method reflectively.","triggerScenarios":"Calling build() on the completion callback builder without invoking .bean(...) with the Spring bean / object holding the annotated method.","commonSituations":"Manual callback registration outside of Spring context (no bean supplied); bean resolution returning null because the class was not registered as a bean.","solutions":["Call .bean(...) with the object instance declaring the @McpComplete method before build()","Verify the annotated class is registered as a Spring bean so the scanner can pass it to the builder"],"exampleFix":"// before\nvar callback = builder().method(method).prompt(\"lang\").build();\n// after\nvar callback = builder().bean(completionService).method(method).prompt(\"lang\").build();","handlingStrategy":"validation","validationCode":"if (targetBean == null) throw new IllegalStateException(\"Completion callback builder requires .bean(...) before build()\");","typeGuard":"boolean readyToBuild = targetBean != null && methodRef != null;","tryCatchPattern":"try {\n    return builder().bean(bean).method(m).build();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().equals(\"Bean must not be null\")) { /* ensure bean was set / resolved from Spring context */ }\n    throw e;\n}","preventionTips":["Pass the Spring bean instance (via ApplicationContext.getBean) when registering manually","Check for null bean resolution before building; assert the annotated class is a registered bean"],"tags":["mcp","builder-validation","null"],"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"}