spring-projects/spring-ai · error · IllegalArgumentException

Method must not be null

Error message

Method must not be null

What it means

AbstractMcpCompleteMethodCallback.validateMethod() first checks that the Method argument is non-null before validating its return type and parameters. A null Method means the framework could not resolve the annotated method (e.g., wrong method name in configuration or a null passed programmatically), and registration fails immediately with this IllegalArgumentException.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/AbstractMcpCompleteMethodCallback.java:126

			this.uriVariables = this.uriTemplateManager.getVariableNames();
		}
		else {
			this.uriTemplateManager = null;
			this.uriVariables = new ArrayList<>();
		}
	}

	/**
	 * Validates that the method signature is compatible with the complete 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 complete 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. Pass the actual reflected Method instance of your completion handler to the callback/builder.
  2. Check any reflection lookup result for null before constructing the callback.
  3. Prefer annotation-based registration so the framework resolves the Method itself.

Example fix

// before
Method m = bean.getClass().getMethod("onComplete"); // NoSuchMethod risk / unchecked
callback = new CallbackImpl(null, bean, ...); // throws
// after
Method m = bean.getClass().getMethod("onComplete", List.class);
Assert.notNull(m, "method missing");
callback = new CallbackImpl(m, bean, ...);
Defensive patterns

Strategy: validation

Validate before calling

if (method == null) throw new IllegalStateException("completion method could not be resolved; check registration");

Type guard

boolean hasMethod = (method instanceof java.lang.reflect.Method m) && m.getDeclaringClass().isInstance(bean);
if (!hasMethod) { /* fix registration before constructing callback */ }

Prevention

When it happens

Trigger: Passing null as the Method to the callback constructor or builder, or programmatic registration where reflection (e.g., Class.getMethod(...)) returned null or the lookup result was not checked.

Common situations: Typos in method names used for programmatic registration; refactoring away a method still referenced by name; constructing the callback manually in tests.

Related errors


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