spring-projects/spring-ai · error · IllegalArgumentException

Method must not be null

Error message

Method must not be null

What it means

AbstractMcpProgressMethodCallback.validateMethod rejects a null Method reference before performing signature validation. This is a defensive precondition: progress callbacks are built reflectively from an annotated method, and a null there indicates a programming error in the registration code, not a user-facing configuration problem.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/progress/AbstractMcpProgressMethodCallback.java:66

		Assert.notNull(method, "Method can't be null!");
		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 progress 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 progress 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. Fix the upstream reflective lookup so it returns the actual Method (correct name and parameter types).
  2. Assert non-null right after getMethod/getDeclaredMethod and fail with a descriptive message.
  3. Prefer obtaining the Method from the annotation-scanning API instead of manual reflection.
  4. In tests, pass Method XXX.class.getDeclaredMethod("name", ParamType.class) rather than null placeholders.

Example fix

// before
Method m = null; // lookup failed silently
new MyProgressCallback(bean, m);
// after
Method m = bean.getClass().getDeclaredMethod("onProgress", ProgressNotification.class);
Objects.requireNonNull(m, "progress handler method not found");
new MyProgressCallback(bean, m);
Defensive patterns

Strategy: validation

Validate before calling

Method m = bean.getClass().getDeclaredMethod("onProgress", ProgressNotification.class);
Objects.requireNonNull(m, "progress handler method not found on " + bean.getClass());

Type guard

static Method requireMethod(Class<?> type, String name, Class<?>... params) throws NoSuchMethodException {
    return Objects.requireNonNull(type.getDeclaredMethod(name, params), "method not found: " + name);
}

Try / catch

try {
    new ProgressCallback(bean, method);
} catch (IllegalArgumentException e) {
    logger.error("Callback construction failed: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling a progress callback builder/constructor (e.g. AbstractMcpElicitationMethodCallback or a progress callback constructor) with null for the Method argument, typically because reflection lookup of the annotated method returned null (wrong method name, annotation not present).

Common situations: Looking up a method by name via Class.getMethod with a typo, catching the exception and passing null onward; building callbacks manually in tests; conditional registration code that skips annotation detection but still constructs the callback.

Related errors


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