spring-projects/spring-ai · error

Bean must not be null

Error message

Bean must not be null

What it means

The same builder validate() step also requires `bean` — the object instance whose method will be reflectively invoked on each tool-list-changed notification. Without a bean instance, calling method.invoke would have no target, so the library throws IllegalArgumentException during build().

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/tool/AbstractMcpToolListChangedMethodCallback.java:211

		 * @param toolListChanged The tool list changed annotation
		 * @return This builder
		 */
		@SuppressWarnings("unchecked")
		public T toolListChanged(McpToolListChanged toolListChanged) {
			// 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. Call .bean(instance) on the builder, passing the actual bean that owns the handler method
  2. For static-style handlers, still pass an instance (e.g. an empty holder) since Method.invoke requires a receiver for instance methods; or declare the handler as a real instance method
  3. Verify bean initialization order so the bean is non-null at registration time (e.g. inject it rather than reading a nullable field)

Example fix

// before
new SyncMcpToolListChangedMethodCallback.Builder().method(m).build();
// after
new SyncMcpToolListChangedMethodCallback.Builder().bean(myHandler).method(m).build();
Defensive patterns

Strategy: validation

Validate before calling

java.util.Objects.requireNonNull(bean, "builder.bean(Object) is required before build()");

Type guard

static boolean beanReady(Object bean) { return bean != null; }

Try / catch

try { return builder.bean(bean).method(method).build(); } catch (IllegalArgumentException e) { throw new IllegalStateException("Builder missing bean: " + e.getMessage(), e); }

Prevention

When it happens

Trigger: Calling builder.build() with .method(m) set but no .bean(instance), e.g. building from a Class instead of an instance: new Builder().method(beanClass.getMethod(...)).build() — bean == null triggers this message.

Common situations: Developers assuming static-method handlers need no bean; the library still requires a target object. Also common when the bean is created lazily or by a context that hasn't initialized yet, leaving the field null.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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