{"record":{"id":"2d6723a3613e57c1","repo":"spring-projects/spring-ai","slug":"bean-must-not-be-null-2d6723","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/resource/AbstractMcpResourceListChangedMethodCallback.java","lineNumber":212,"sourceCode":"\t\t * @param resourceListChanged The resource list changed annotation\n\t\t * @return This builder\n\t\t */\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tpublic T resourceListChanged(McpResourceListChanged resourceListChanged) {\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":194,"sourceCodeEnd":225,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/resource/AbstractMcpResourceListChangedMethodCallback.java#L194-L225","documentation":"The callback builder requires the bean instance on which the consumer method will be invoked. validate() throws this when the bean field is null. Without a bean the reflective Method.invoke target is undefined, so building is refused.","triggerScenarios":"Building a Sync/AsyncMcpResourceListChangedMethodCallback with .method(...) set but omitting .bean(Object).","commonSituations":"Programmatic registration where the developer passes a null Spring bean (failed injection) or forgets the .bean(...) call when constructing the builder by hand.","solutions":["Call .bean(...) with the object instance that declares the consumer method.","Ensure dependency injection succeeded so the bean reference is not null.","Use the annotation-driven registration path, which wires method and bean together automatically."],"exampleFix":"// before\nnew AsyncMcpResourceListChangedMethodCallback.Builder().method(m).build();\n// after\nnew AsyncMcpResourceListChangedMethodCallback.Builder().method(m).bean(handler).build();","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(bean, \"bean must be set before 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 IllegalStateException(\"Builder misconfigured: call .bean(...) before .build()\", e);\n    }\n    throw e;\n}","preventionTips":["Verify Spring injection completed (bean != null) before registration.","Set both .method(...) and .bean(...) in the same builder chain."],"tags":["java","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"}