spring-projects/spring-ai · error · java.lang.IllegalArgumentException
Method cannot have more than one @McpProgressToken parameter
Error message
Method cannot have more than one @McpProgressToken parameter: {method.getName()} in {method.getDeclaringClass().getName()} What it means
validateParameters() walks the @McpPrompt method's parameters and allows at most one parameter annotated with @McpProgressToken; the framework maps the incoming progress token to it. Declaring two or more such parameters is ambiguous and rejected with IllegalArgumentException naming the method and declaring class.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/AbstractMcpPromptMethodCallback.java:130
java.lang.reflect.Parameter[] parameters = method.getParameters();
// Check for duplicate parameter types
boolean hasExchangeParam = false;
boolean hasRequestParam = false;
boolean hasMapParam = false;
boolean hasProgressTokenParam = false;
boolean hasMetaParam = false;
boolean hasRequestContextParam = false;
for (java.lang.reflect.Parameter param : parameters) {
Class<?> paramType = param.getType();
this.validateParamType(paramType);
// 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
- Remove the extra @McpProgressToken annotation so exactly one parameter carries it.
- If both values are needed, capture the token once and pass it to a shared helper instead of injecting it twice.
- Review the method signature and keep only supported parameter kinds (single prompt arg, McpMeta, single context, single @McpProgressToken).
Example fix
// before
@McpPrompt(name = "p")
public String complete(String q, @McpProgressToken String t1, @McpProgressToken String t2) { ... }
// after
@McpPrompt(name = "p")
public String complete(String q, @McpProgressToken String token) { ... } Defensive patterns
Strategy: validation
Validate before calling
long tokenParams = Arrays.stream(method.getParameters())
.filter(p -> p.isAnnotationPresent(McpProgressToken.class)).count();
if (tokenParams > 1) throw new IllegalStateException("Only one @McpProgressToken parameter allowed"); Try / catch
try { registry.register(bean); } catch (IllegalArgumentException e) { log.error("Invalid @McpPrompt signature: {}", e.getMessage()); } Prevention
- Count @McpProgressToken annotations when writing prompt methods
- After copy-pasting parameters, re-read the full signature
- Keep a project convention: one progress token parameter max, injected once and reused
When it happens
Trigger: An @McpPrompt method declaring two parameters annotated @McpProgressToken, e.g. complete(String value, @McpProgressToken String t1, @McpProgressToken String t2).
Common situations: Copy-pasting a parameter block and forgetting to remove the duplicate @McpProgressToken annotation; refactoring that added a second progress-aware parameter; misunderstanding that only one token can be injected per callback.
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:
- Method must have exactly 1 parameter (List<McpSchema.Resourc
- Single parameter must be of type ElicitRequest:
- Currently only methods with a single ElicitRequest parameter
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6dc06f79e3917a5d.
Report an issue: GitHub.