spring-projects/spring-ai · error · IllegalArgumentException
Method cannot have more than one @McpProgressToken parameter
Error message
Method cannot have more than one @McpProgressToken parameter:
What it means
A completion method may accept at most one parameter annotated with @McpProgressToken (the progress token injected by the framework). validateParameters() throws this IllegalArgumentException when it encounters a second @McpProgressToken-annotated parameter, at registration time.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/AbstractMcpCompleteMethodCallback.java:183
+ nonSpecialParamCount + " parameters");
}
// Check parameter types
boolean hasExchangeParam = false;
boolean hasTransportContext = false;
boolean hasRequestParam = false;
boolean hasArgumentParam = false;
boolean hasProgressTokenParam = false;
boolean hasMetaParam = false;
boolean hasRequestContextParam = false;
for (Parameter param : parameters) {
Class<?> paramType = param.getType();
// Skip @McpProgressToken annotated parameters from validation
if (param.isAnnotationPresent(McpProgressToken.class)) {
if (hasProgressTokenParam) {
throw new IllegalArgumentException("Method cannot have more than one @McpProgressToken parameter: "
+ method.getName() + " in " + method.getDeclaringClass().getName());
}
hasProgressTokenParam = true;
continue;
}
// Skip McpMeta parameters from validation
if (McpMeta.class.isAssignableFrom(paramType)) {
if (hasMetaParam) {
throw new IllegalArgumentException("Method cannot have more than one McpMeta parameter: "
+ method.getName() + " in " + method.getDeclaringClass().getName());
}
hasMetaParam = true;
continue;
}
if (McpSyncRequestContext.class.isAssignableFrom(paramType)) {
if (hasRequestContextParam) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Keep exactly one @McpProgressToken-annotated parameter (or none).
- Remove the duplicate annotation/parameter.
- If multiple values are needed, read them from the request context instead.
Example fix
// before
public void complete(String value, @McpProgressToken String t1, @McpProgressToken String t2) { }
// after
public void complete(String value, @McpProgressToken String token) { } Defensive patterns
Strategy: validation
Validate before calling
long tokens = Arrays.stream(method.getParameters())
.filter(p -> p.isAnnotationPresent(McpProgressToken.class)).count();
if (tokens > 1) throw new IllegalStateException("duplicate @McpProgressToken in " + method.getName()); Prevention
- Use at most one @McpProgressToken parameter per handler.
- Watch for duplicated parameters after merges or code generation.
When it happens
Trigger: Declaring two or more parameters annotated @McpProgressToken on a single @McpComplete-annotated method.
Common situations: Copy-paste duplication of a parameter line; misunderstanding the annotation as per-argument rather than a singleton injection; merge conflicts leaving duplicated parameters.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Method cannot have more than one McpMeta parameter: {method}
- Method cannot have more than one request context parameter:
- Either prompt or uri must be provided!
- Only one of prompt or uri can be provided!
- Method can have at most 3 input parameters (excluding @McpPr
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/eeaa01581668175e.
Report an issue: GitHub.