spring-projects/spring-ai · error · IllegalArgumentException

Currently only methods with a single CreateMessageRequest pa

Error message

Currently only methods with a single CreateMessageRequest parameter are supported: {methodName} in {className} has {paramCount} parameters

What it means

The sampling callback currently supports only the single-parameter form: exactly one CreateMessageRequest argument. validateParameters() rejects methods with 2+ parameters, including multi-arg injections of individual request fields, because that support is not yet implemented (marked TODO in source).

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/sampling/AbstractMcpSamplingMethodCallback.java:111

			throw new IllegalArgumentException(
					"Method must have at least 1 parameter (CreateMessageRequest): " + method.getName() + " in "
							+ method.getDeclaringClass().getName() + " has " + parameters.length + " parameters");
		}

		// Check parameter types
		if (parameters.length == 1) {
			// Single parameter must be CreateMessageRequest
			if (!CreateMessageRequest.class.isAssignableFrom(parameters[0].getType())) {
				throw new IllegalArgumentException("Single parameter must be of type CreateMessageRequest: "
						+ method.getName() + " in " + method.getDeclaringClass().getName() + " has parameter of type "
						+ parameters[0].getType().getName());
			}
		}
		else {
			// TODO: Support for multiple parameters corresponding to CreateMessageRequest
			// fields
			// For now, we only support the single parameter version
			throw new IllegalArgumentException(
					"Currently only methods with a single CreateMessageRequest parameter are supported: "
							+ method.getName() + " in " + method.getDeclaringClass().getName() + " has "
							+ parameters.length + " parameters");
		}
	}

	/**
	 * 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, request).
	 * @param method The method to build arguments for
	 * @param exchange The server exchange
	 * @param request The sampling request
	 * @return An array of arguments for the method invocation
	 */
	protected Object[] buildArgs(Method method, Object exchange, CreateMessageRequest request) {
		Parameter[] parameters = method.getParameters();

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Reduce the signature to a single CreateMessageRequest parameter
  2. Move any additional data derivation (context, options) inside the method body, reading from the CreateMessageRequest
  3. Watch the library for the multi-parameter TODO being implemented, or file/request the feature upstream

Example fix

// before
@McpSampling
public String sample(CreateMessageRequest request, McpTransportContext ctx) { return "reply"; }
// after
@McpSampling
public String sample(CreateMessageRequest request) { /* derive context from request */ return "reply"; }
Defensive patterns

Strategy: validation

Validate before calling

for (Method m : clazz.getDeclaredMethods()) {
    if (m.isAnnotationPresent(McpSampling.class)
            && m.getParameterCount() != 1) {
        throw new IllegalStateException("Sampling method " + m.getName()
            + " must have exactly one CreateMessageRequest parameter");
    }
}

Try / catch

try {
    registerSamplingCallback(method);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("only methods with a single CreateMessageRequest")) {
        log.error("Too many parameters on sampling method {}: {}", method, e.getMessage());
    } else { throw e; }
}

Prevention

When it happens

Trigger: Annotating a sampling handler with two or more parameters, e.g. `void handler(CreateMessageRequest req, McpTransportContext ctx)` or splitting request fields into separate parameters.

Common situations: Developers mirror the tool/prompt callback style, which supports extra context parameters, and assume sampling does the same; or they add convenience parameters like locale or model hints.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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