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 invocation

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Change the parameter type to String and parse/convert manually inside the method
  2. Ensure the parameter is annotated with @McpProgressToken if it is meant to be a progress token, so it is skipped
  3. 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

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/55a98ed7d987e365. Report an issue: GitHub.