spring-projects/spring-ai · error · IllegalArgumentException
Method can have at most 2 input parameters (excluding @McpPr
Error message
Method can have at most 2 input parameters (excluding @McpProgressToken and McpMeta) when no URI variables are present: ${method} in ${declaringClass} has ${count} non-special parameters What it means
A @McpResource method without URI variables may declare at most 2 non-special input parameters (special = @McpProgressToken-annotated and McpMeta parameters). validateParametersWithoutUriVariables counts ordinary parameters and throws IllegalArgumentException when more than 2 remain, since with no URI template there are at most a request + request-context slot.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java:189
*/
protected void validateParametersWithoutUriVariables(Method method) {
Parameter[] parameters = method.getParameters();
// Count parameters excluding @McpProgressToken and McpMeta annotated ones
int nonSpecialParamCount = 0;
for (Parameter param : parameters) {
if (!param.isAnnotationPresent(McpProgressToken.class) && !McpMeta.class.isAssignableFrom(param.getType())
&& !McpSyncRequestContext.class.isAssignableFrom(param.getType())
&& !McpAsyncRequestContext.class.isAssignableFrom(param.getType())
&& !isExchangeOrContextType(param.getType())) {
nonSpecialParamCount++;
}
}
// Check parameter count - must have at most 2 non-special parameters
if (nonSpecialParamCount > 2) {
throw new IllegalArgumentException(
"Method can have at most 2 input parameters (excluding @McpProgressToken and McpMeta) when no URI variables are present: "
+ method.getName() + " in " + method.getDeclaringClass().getName() + " has "
+ nonSpecialParamCount + " non-special parameters");
}
// Check parameter types
boolean hasValidParams = false;
boolean hasExchangeParam = false;
boolean hasRequestOrUriParam = false;
boolean hasMetaParam = false;
boolean hasRequestContextParam = false;
for (Parameter param : parameters) {
// Skip @McpProgressToken annotated parameters
if (param.isAnnotationPresent(McpProgressToken.class)) {
continue;
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Reduce the method to at most 2 non-special parameters (e.g. one request object plus one context).
- Group extra inputs into a single request/record parameter.
- Annotate auxiliary parameters with @McpProgressToken or use McpMeta so they are excluded from the count only if semantically correct.
- If the resource URI actually has URI variables, declare them; the URI-variable validation path allows different signatures.
Example fix
// before
@McpResource(uri = "file:///docs")
public String read(String path, String encoding, int maxLines) { ... }
// after
@McpResource(uri = "file:///docs")
public String read(ReadOptions options) { ... } // group params into one request object Defensive patterns
Strategy: validation
Validate before calling
static boolean resourceParamCountValid(Method m, int uriVarCount) {
if (uriVarCount > 0) return true; // different rules apply
long nonSpecial = java.util.Arrays.stream(m.getParameters())
.filter(p -> p.getAnnotation(McpProgressToken.class) == null
&& p.getType() != McpMeta.class)
.count();
return nonSpecial <= 2;
} Try / catch
try {
resourceManager.register(callback);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("@McpResource signature has too many parameters", e);
} Prevention
- Keep URI-variable-free resource methods to at most 2 non-special parameters.
- Group extra inputs into one request object/record.
- Review signatures when copy-pasting tool methods into resource methods.
When it happens
Trigger: Declaring a @McpResource method with 3+ ordinary parameters (e.g. multiple request objects or plain values) while the resource URI has no URI variables; each parameter not annotated with @McpProgressToken and not of type McpMeta increments the count.
Common situations: Copy-pasting tool method signatures into resource methods; trying to pass extra options by adding parameters; misunderstanding that URI variables count as regular parameters when present (different validator applies).
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 must not be null
- Method cannot have more than one request context parameter:
- Sync complete methods should use McpSyncRequestContext inste
- Method must have parameters for all URI variables. Expected
- Method must have exactly 1 parameter (List<McpSchema.Resourc
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/04ee32626a5bbed8.
Report an issue: GitHub.