spring-projects/spring-ai · error · IllegalArgumentException

Method must have either 1 parameter (LoggingMessageNotificat

Error message

Method must have either 1 parameter (LoggingMessageNotification) or 3 parameters (LoggingLevel, String, String): 

What it means

validateParameters() in AbstractMcpLoggingMethodCallback requires an @McpLogging handler to accept exactly 1 parameter (a LoggingMessageNotification) or exactly 3 parameters (LoggingLevel, String, String). Any other arity is rejected with IllegalArgumentException at registration time.

Source

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

	 * 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.
	 * @param method The method to validate
	 * @throws IllegalArgumentException if the parameters are not compatible
	 */
	protected void validateParameters(Method method) {
		Parameter[] parameters = method.getParameters();

		// Check parameter count - must have either 1 or 3 parameters
		if (parameters.length != 1 && parameters.length != 3) {
			throw new IllegalArgumentException(
					"Method must have either 1 parameter (LoggingMessageNotification) or 3 parameters (LoggingLevel, String, String): "
							+ method.getName() + " in " + method.getDeclaringClass().getName() + " has "
							+ parameters.length + " parameters");
		}

		// Check parameter types
		if (parameters.length == 1) {
			// Single parameter must be LoggingMessageNotification
			if (!LoggingMessageNotification.class.isAssignableFrom(parameters[0].getType())) {
				throw new IllegalArgumentException("Single parameter must be of type LoggingMessageNotification: "
						+ method.getName() + " in " + method.getDeclaringClass().getName() + " has parameter of type "
						+ parameters[0].getType().getName());
			}
		}
		else {
			// Three parameters must be LoggingLevel, String, String
			if (!LoggingLevel.class.isAssignableFrom(parameters[0].getType())) {
				throw new IllegalArgumentException("First parameter must be of type LoggingLevel: " + method.getName()

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Change the handler to a single LoggingMessageNotification parameter
  2. Or use the 3-parameter form (LoggingLevel level, String logger, String message)
  3. Remove extra parameters and obtain context via fields or the exchange passed at construction

Example fix

// before
@McpLogging(clients = "client1")
public void onLog(McpSyncServerExchange exchange, LoggingMessageNotification n) { ... }
// after
@McpLogging(clients = "client1")
public void onLog(LoggingMessageNotification n) { ... }
Defensive patterns

Strategy: validation

Validate before calling

int n = loggingMethod.getParameterCount();
if (n != 1 && n != 3) {
    throw new IllegalStateException(loggingMethod.getName() + " must take 1 or 3 parameters, has " + n);
}

Type guard

static boolean isValidLoggingArity(Method m) {
    return m.getParameterCount() == 1 || m.getParameterCount() == 3;
}

Prevention

When it happens

Trigger: Registering a logging handler with 0, 2, or 4+ parameters; using varargs; passing a method intended for a different MCP annotation type.

Common situations: Developer writes a handler with extra context parameters (e.g. McpSyncServerExchange plus payload); copy-paste from a tool callback that has different signatures; overload resolution picks the wrong method.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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