spring-projects/spring-ai · error · IllegalArgumentException

Method must not be null

Error message

Method must not be null

What it means

AbstractMcpLoggingMethodCallback.validateMethod() rejects a null Method reference before validating return type and parameters. A logging callback cannot be constructed without a concrete @McpLogging-annotated method to invoke. This is a fail-fast guard, usually reached through subclass builders (e.g. AbstractMcpPromptListChangedMethodCallback-style construction paths).

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/logging/AbstractMcpLoggingMethodCallback.java:68

		Assert.notNull(bean, "Bean can't be null!");

		this.method = method;
		this.bean = bean;
		this.validateMethod(this.method);
	}

	/**
	 * Validates that the method signature is compatible with the logging consumer
	 * callback.
	 * <p>
	 * This method checks that the return type is valid and that the parameters match the
	 * expected pattern.
	 * @param method The method to validate
	 * @throws IllegalArgumentException if the method signature is not compatible
	 */
	protected void validateMethod(Method method) {
		if (method == null) {
			throw new IllegalArgumentException("Method must not be null");
		}

		this.validateReturnType(method);
		this.validateParameters(method);
	}

	/**
	 * Validates that the method return type is compatible with the logging consumer
	 * callback. This method should be implemented by subclasses to handle specific return
	 * type validation.
	 * @param method The method to validate
	 * @throws IllegalArgumentException if the return type is not compatible
	 */
	protected abstract void validateReturnType(Method method);

	/**
	 * Validates method parameters. This method provides common validation logic and
	 * delegates exchange type checking to subclasses.

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Ensure the Method reference passed to the callback constructor/builder is non-null
  2. Fix reflective lookup (getDeclaredMethod/getMethod) so it resolves the @McpLogging method
  3. Call method(...) on the builder before build()

Example fix

// before
new SyncMcpLoggingMethodCallback.Builder().bean(handler).build();
// after
Method m = handler.getClass().getDeclaredMethod("onLog", LoggingMessageNotification.class);
new SyncMcpLoggingMethodCallback.Builder().method(m).bean(handler).build();
Defensive patterns

Strategy: validation

Validate before calling

Method m = resolveLoggingMethod(handler); // must not return null
if (m == null) { throw new IllegalStateException("@McpLogging method not found on " + handler.getClass()); }

Type guard

static boolean isResolvable(Class<?> handler, String name, Class<?>... params) {
    try { return handler.getDeclaredMethod(name, params) != null; }
    catch (NoSuchMethodException e) { return false; }
}

Prevention

When it happens

Trigger: Passing null as the method argument when constructing a logging method callback directly or via a builder that does not set the method before build().

Common situations: Programmatic callback registration where the method is looked up reflectively and the lookup returns null; a builder's method(...) setter never called before build().

Related errors


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