spring-projects/spring-ai · error · IllegalArgumentException

Method cannot have more than one McpMeta parameter: ${method

Error message

Method cannot have more than one McpMeta parameter: ${method} in ${declaringClass}

What it means

Thrown when a resource method declares more than one McpMeta parameter. Only one McpMeta object (carrying client-provided metadata) is bound per call, so a duplicate is ambiguous and rejected during validation.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java:236

									+ method.getName() + " in " + method.getDeclaringClass().getName());
				}
				hasRequestContextParam = true;
			}
			else if (McpAsyncRequestContext.class.isAssignableFrom(paramType)) {
				if (hasRequestContextParam) {
					throw new IllegalArgumentException("Method cannot have more than one request context parameter: "
							+ method.getName() + " in " + method.getDeclaringClass().getName());
				}
				if (McpPredicates.isNotReactiveReturnType.test(method)) {
					throw new IllegalArgumentException(
							"Async complete methods should use McpAsyncRequestContext instead of McpSyncRequestContext parameter: "
									+ method.getName() + " in " + method.getDeclaringClass().getName());
				}
				hasRequestContextParam = true;
			}
			else 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;
			}
			else if (isExchangeOrContextType(paramType)) {
				if (hasExchangeParam) {
					throw new IllegalArgumentException("Method cannot have more than one exchange parameter: "
							+ method.getName() + " in " + method.getDeclaringClass().getName());
				}
				hasExchangeParam = true;
			}
			else if (ReadResourceRequest.class.isAssignableFrom(paramType)
					|| String.class.isAssignableFrom(paramType)) {
				if (hasRequestOrUriParam) {
					throw new IllegalArgumentException(
							"Method cannot have more than one ReadResourceRequest or String parameter: "
									+ method.getName() + " in " + method.getDeclaringClass().getName());
				}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Remove one of the McpMeta parameters, keeping exactly one
  2. If extra data is needed, bundle it in a custom object or read from the single McpMeta

Example fix

// before
public String read(String uri, McpMeta meta1, McpMeta meta2) { ... }
// after
public String read(String uri, McpMeta meta) { ... }
Defensive patterns

Strategy: validation

Validate before calling

long metaCount = Arrays.stream(method.getParameterTypes())
    .filter(McpMeta.class::isAssignableFrom).count();
if (metaCount > 1) throw new IllegalStateException(method + " declares " + metaCount + " McpMeta parameters");

Try / catch

try { provider.build(...); }
catch (IllegalArgumentException e) {
  if (e.getMessage().contains("more than one McpMeta parameter")) { /* deduplicate McpMeta params */ }
  else throw e;
}

Prevention

When it happens

Trigger: A @McpResource method (no URI variables) has two parameters assignable to McpMeta; detected when the second McpMeta-typed parameter is seen while hasMetaParam is true.

Common situations: Accidentally duplicating McpMeta when merging parameters from two handler methods; copy-paste of a signature block; IDE auto-complete adding a second meta param.

Understand the failure class

Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.

Related errors


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