spring-projects/spring-ai · error · IllegalArgumentException

Second parameter must be of type String:

Error message

Second parameter must be of type String: 

What it means

Thrown during parameter validation of an @McpLogging method callback when the callback declares multiple parameters and its second parameter's type is not assignable to String. The multi-parameter callback signature must be (LoggingLevel, String, String); this guard fires at method-registration time (not runtime message handling) because the second parameter carries the logger name and something else was declared. It is a fail-fast configuration error: the offending Method can never receive a valid logging notification.

Source

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

		// 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()
						+ " in " + method.getDeclaringClass().getName() + " has parameter of type "
						+ parameters[0].getType().getName());
			}
			if (!String.class.isAssignableFrom(parameters[1].getType())) {
				throw new IllegalArgumentException("Second parameter must be of type String: " + method.getName()
						+ " in " + method.getDeclaringClass().getName() + " has parameter of type "
						+ parameters[1].getType().getName());
			}
			if (!String.class.isAssignableFrom(parameters[2].getType())) {
				throw new IllegalArgumentException("Third parameter must be of type String: " + method.getName()
						+ " in " + method.getDeclaringClass().getName() + " has parameter of type "
						+ parameters[2].getType().getName());
			}
		}
	}

	/**
	 * Builds the arguments array for invoking the method.
	 * <p>
	 * This method constructs an array of arguments based on the method's parameter types
	 * and the available values (exchange, notification).
	 * @param method The method to build arguments for
	 * @param exchange The server exchange

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Change the second parameter to String (the log message)

Example fix

// before
@McpLogging(clients = "client1")
public void onLog(LoggingLevel level, Logger logger, String msg) { ... }
// after
@McpLogging(clients = "client1")
public void onLog(LoggingLevel level, String loggerName, String msg) { ... }
Defensive patterns

Strategy: validation

Validate before calling

if (m.getParameterCount() == 3
        && !String.class.isAssignableFrom(m.getParameterTypes()[1])) {
    throw new IllegalStateException("second param must be String");
}

Type guard

static boolean secondParamIsString(Method m) {
    return m.getParameterCount() == 3
        && String.class.isAssignableFrom(m.getParameterTypes()[1]);
}

Prevention

When it happens

Trigger: Registering a @McpLogging method like (LoggingLevel, Logger, String) or (LoggingLevel, Integer, String).

Common situations: Developer passes a Logger/LoggerName object instead of the plain logger-name String; misordered parameters from another framework's handler signature.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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