spring-projects/spring-ai · error · IllegalArgumentException
URI variable parameters must be of type String: ${method} in
Error message
URI variable parameters must be of type String: ${method} in ${declaringClass}, parameter of type ${paramType} is not valid What it means
Thrown when a non-special parameter of an @McpResource method with URI variables is not assignable to any of the allowed types (McpSyncRequestContext, McpAsyncRequestContext, exchange/context types, ReadResourceRequest, McpMeta, String). URI variable parameters must be String.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java:383
throw new IllegalArgumentException(
"Method must have parameters for all URI variables. Expected " + this.uriVariables.size()
+ " URI variable parameters, but found " + uriVarParamCount + ": " + method.getName()
+ " in " + method.getDeclaringClass().getName() + ". URI variables: " + this.uriVariables);
}
// Check that all non-special parameters are String type (for URI variables)
for (Parameter param : parameters) {
// Skip @McpProgressToken annotated parameters
if (param.isAnnotationPresent(McpProgressToken.class)) {
continue;
}
Class<?> paramType = param.getType();
if (!McpSyncRequestContext.class.isAssignableFrom(paramType)
&& !McpAsyncRequestContext.class.isAssignableFrom(paramType) && !isExchangeOrContextType(paramType)
&& !ReadResourceRequest.class.isAssignableFrom(paramType)
&& !McpMeta.class.isAssignableFrom(paramType) && !String.class.isAssignableFrom(paramType)) {
throw new IllegalArgumentException("URI variable parameters must be of type String: " + method.getName()
+ " in " + method.getDeclaringClass().getName() + ", parameter of type " + paramType.getName()
+ " is not valid");
}
}
}
protected abstract Object assignExchangeType(Class<?> paramType, Object exchange);
/**
* 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, URI variables, progress token).
* @param method The method to build arguments for
* @param exchange The server exchange
* @param request The resource request
* @param uriVariableValues Map of URI variable names to their values
* @return An array of arguments for the method invocationView on GitHub (pinned to 98a7beda4f)
Solutions
- Change the parameter type to String and parse/convert manually inside the method
- Ensure the parameter is annotated with @McpProgressToken if it is meant to be a progress token, so it is skipped
- Remove the parameter if it is not needed (remember URI variable count must match)
Example fix
// before
@McpResource(uri = "docs://{id}")
public String read(UUID id) { ... }
// after
@McpResource(uri = "docs://{id}")
public String read(String id) { return read(UUID.fromString(id)); } Defensive patterns
Strategy: validation
Validate before calling
for (Parameter p : m.getParameters()) {
Class<?> t = p.getType();
if (!String.class.isAssignableFrom(t) && !isSpecialParam(t) && !p.isAnnotationPresent(McpProgressToken.class))
throw new IllegalStateException("URI variable parameter " + p + " must be String");
} Prevention
- Always declare URI variable parameters as String and parse manually
- Do not use UUID/Integer/DTO types in resource method signatures
- Annotate progress-token params with @McpProgressToken so they are skipped
When it happens
Trigger: Declaring a URI variable parameter as Integer, UUID, or a custom type (e.g. read(String table, int id)) with a variable URI; validateParametersWithUriVariables iterates parameters and throws for any type outside the allowed set.
Common situations: Using Integer/UUID for an id path variable expecting automatic conversion; leaving a DTO parameter in the signature; changing a String param to a typed one during refactoring.
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
- Single parameter must be of type ProgressNotification: {meth
- Method must have parameters for all URI variables. Expected
- URI must not be null or empty
- Method must have exactly 1 parameter (List<McpSchema.Resourc
- Parameter must be of type List<McpSchema.Resource>:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/55a98ed7d987e365.
Report an issue: GitHub.