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

  1. Set both method and bean on the builder before calling build()
  2. If discovering methods reflectively, verify the declaring class is itself the bean instance passed in
  3. 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

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/8f58e7975e934571. Report an issue: GitHub.