spring-projects/spring-ai · error · IllegalArgumentException

Third parameter must be of type String:

Error message

Third 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 third parameter's type is not assignable to String. The multi-parameter form must be (LoggingLevel, String, String), where the third parameter carries the log message payload; a non-String third parameter means the callback can never be invoked with a decoded notification. This fails fast at registration time via validateMethod rather than deferring the mismatch to message delivery.

Solutions

  1. Change the third parameter to String (the logger name)

Example fix

// before
@McpLogging(clients = "client1")
public void onLog(LoggingLevel level, String logger, Map<String, Object> data) { ... }
// after
@McpLogging(clients = "client1")
public void onLog(LoggingLevel level, String logger, String message) { ... }
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Prevention

When it happens

Trigger: Registering a @McpLogging method like (LoggingLevel, String, Object) or (LoggingLevel, String, Map).

Common situations: Developer expects structured payload data as the third argument; message passed as a custom type; refactoring changed the parameter type after registration.

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/f64c57c637332d9f. Report an issue: GitHub.

Appendix: source

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

				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
	 * @param notification The logging message notification
	 * @return An array of arguments for the method invocation
	 */
	protected Object[] buildArgs(Method method, Object exchange, LoggingMessageNotification notification) {
		Parameter[] parameters = method.getParameters();

View on GitHub (pinned to 98a7beda4f)