{"record":{"id":"33ede3d889cefc15","repo":"spring-projects/spring-ai","slug":"bean-must-not-be-null-33ede3","errorCode":null,"errorMessage":"Bean must not be null","messagePattern":"Bean 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/progress/AbstractMcpProgressMethodCallback.java","lineNumber":240,"sourceCode":"\t\t * @param progress The progress annotation\n\t\t * @return This builder\n\t\t */\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tpublic T progress(McpProgress progress) {\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":222,"sourceCodeEnd":253,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/progress/AbstractMcpProgressMethodCallback.java#L222-L253","documentation":"The builder for McpProgress method callbacks requires a target bean (the object instance whose method will be invoked). validate() throws this IllegalArgumentException when the builder's bean field is null at build() time. Without a bean the callback has no instance to invoke the validated Method on.","triggerScenarios":"Calling AsyncMcpProgressMethodCallback.builder().method(m).build() without calling .bean(instance), or passing a null bean reference obtained from a failed lookup/injection.","commonSituations":"Manual (non-Spring) registration where the developer forgets the bean; a Spring bean injection field that is null because component scanning missed the class; test code constructing builders directly.","solutions":["Call .bean(Object) on the builder with the instance that owns the annotated method.","Fix bean retrieval (e.g. applicationContext.getBean(...)) so it returns a non-null instance.","Verify Spring wiring/scanning so the handler bean is actually created before registration."],"exampleFix":"// before\nvar callback = AsyncMcpProgressMethodCallback.builder()\n    .method(m).build();\n// after\nvar callback = AsyncMcpProgressMethodCallback.builder()\n    .method(m).bean(progressHandlerBean).build();","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(bean, \"target bean must be provided\");\nvar cb = AsyncMcpProgressMethodCallback.builder().method(method).bean(bean).build();","typeGuard":"function requiresBean(b) { if (b == null || b.bean == null) throw new Error('builder.bean() not set'); return b; }","tryCatchPattern":"try {\n    return builder.method(method).build();\n} catch (IllegalArgumentException e) {\n    if (\"Bean must not be null\".equals(e.getMessage())) {\n        throw new IllegalStateException(\"bean not injected — check Spring wiring/scanning\", e);\n    }\n    throw e;\n}","preventionTips":["Always chain .method(...).bean(...) together in a helper factory method.","Verify the handler bean exists in the application context before registration.","Use constructor injection so the bean reference cannot be null."],"tags":["mcp","builder-validation","null-check","progress-notification"],"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"}