spring-projects/spring-ai · error · IllegalArgumentException
Single parameter must be of type CreateMessageRequest: {meth
Error message
Single parameter must be of type CreateMessageRequest: {methodName} in {className} has parameter of type {paramTypeName} What it means
With exactly one parameter, that parameter must be assignable from CreateMessageRequest, since it receives the sampling request. validateParameters() throws IllegalArgumentException when the single parameter has an incompatible type.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/sampling/AbstractMcpSamplingMethodCallback.java:102
* 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 at least 1 parameter
if (parameters.length < 1) {
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>View on GitHub (pinned to 98a7beda4f)
Solutions
- Change the single parameter type to CreateMessageRequest (or a subclass)
- If you need custom input parsing, accept CreateMessageRequest and map its fields manually inside the method
- Check the MCP SDK version's schema class (io.modelcontextprotocol.spec.McpSchema.CreateMessageRequest) and import the correct one
Example fix
// before
@McpSampling
public String sample(String request) { return "reply"; }
// after
@McpSampling
public String sample(CreateMessageRequest request) { return "reply"; } Defensive patterns
Strategy: type-guard
Validate before calling
for (Method m : clazz.getDeclaredMethods()) {
if (m.isAnnotationPresent(McpSampling.class)
&& m.getParameterCount() == 1
&& !CreateMessageRequest.class.isAssignableFrom(m.getParameterTypes()[0])) {
throw new IllegalStateException(m.getName()
+ " parameter must be CreateMessageRequest, got "
+ m.getParameterTypes()[0].getName());
}
} Type guard
boolean hasCreateMessageRequestParam(Method m) {
return m.getParameterCount() == 1
&& CreateMessageRequest.class.isAssignableFrom(m.getParameterTypes()[0]);
} Try / catch
try {
registerSamplingCallback(method);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Single parameter must be of type")) {
log.error("Wrong parameter type on sampling method {}: {}", method, e.getMessage());
} else { throw e; }
} Prevention
- Import CreateMessageRequest from the MCP schema package, not a custom DTO
- Pin the spring-ai-mcp version and re-check signatures after upgrades
- Add an ArchUnit or unit test asserting handler parameter types
When it happens
Trigger: Declaring a sampling callback like `void handler(String req)` or `void handler(MyCustomRequest req)` — a single parameter whose type is not CreateMessageRequest (or a subtype).
Common situations: Developers use their own request DTO, a String, or Map<String,Object> instead of the framework's CreateMessageRequest; or they upgraded spring-ai-mcp where the required request type changed.
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
- Parameter must be of type List<McpSchema.Resource>:
- List items must be of type String
- List items must be of type String
- List items must be of type String
- Single parameter must be of type ProgressNotification: {meth
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/b92482bde96463ee.
Report an issue: GitHub.