spring-projects/spring-ai · error · IllegalArgumentException
Bean must not be null
Error message
Bean must not be null
What it means
Abstract builder validate() throws IllegalArgumentException when either the callback's Method or its target bean instance is null. Every sampling method callback builder (sync and async) requires both a reflective Method handle and the bean object it belongs to before it can invoke anything. This is a programming error caught at build time, before any sampling request is served.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/sampling/AbstractMcpSamplingMethodCallback.java:239
* @param sampling The sampling annotation
* @return This builder
*/
@SuppressWarnings("unchecked")
public T sampling(McpSampling sampling) {
// No additional configuration needed from the annotation at this time
return (T) this;
}
/**
* Validate the builder state.
* @throws IllegalArgumentException if the builder state is invalid
*/
protected void validate() {
if (this.method == null) {
throw new IllegalArgumentException("Method must not be null");
}
if (this.bean == null) {
throw new IllegalArgumentException("Bean must not be null");
}
}
/**
* Build the callback.
* @return A new callback instance
*/
public abstract R build();
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Set both method and bean on the builder before calling build()
- If discovering methods reflectively, verify the declaring class is itself the bean instance passed in
- Wrap builder calls in a helper that asserts non-null method/bean pairs
Example fix
// before
McpSamplingMethodCallback cb = new AsyncMcpSamplingMethodCallback.Builder()
.method(method)
.build();
// after
McpSamplingMethodCallback cb = new AsyncMcpSamplingMethodCallback.Builder()
.method(method)
.bean(myService)
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (method == null || bean == null) {
throw new IllegalStateException("Sampling callback needs both method and bean");
}
new AsyncMcpSamplingMethodCallback.Builder().method(method).bean(bean).build(); Type guard
boolean isReady(Builder b) { return b.method != null && b.bean != null; } Prevention
- Always set bean and method together in a small factory helper
- Write a unit test that builds each registered callback at startup
- Fail fast in application startup if any callback construction throws
When it happens
Trigger: Calling .method(m) without .bean(obj), or .bean(obj) without .method(m), then invoking build() on an AbstractMcpSamplingMethodCallback.Builder subclass.
Common situations: Programmatically assembling sampling callbacks where one builder field is conditionally set; refactoring code that drops the bean assignment; building callbacks in a loop where a null element slips in.
Related errors
- Bean must not be null
- Request must not be null
- Sampling not supported by the client:
- Method must not be null
- Request must not be null
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/8f58e7975e934571.
Report an issue: GitHub.