spring-projects/spring-ai · error · java.lang.IllegalArgumentException

Method cannot have more than one request context parameter:

Error message

Method cannot have more than one request context parameter: {method.getName()} in {method.getDeclaringClass().getName()}

What it means

validateParameters() enforces that an @McpPrompt method has at most one request-context parameter. When a parameter is assignable from McpSyncRequestContext, declaring a second context parameter (sync or async) is ambiguous and throws 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:149

							+ 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) {
					throw new IllegalArgumentException("Method cannot have more than one request context parameter: "
							+ method.getName() + " in " + method.getDeclaringClass().getName());
				}
				if (McpPredicates.isReactiveReturnType.test(method)) {
					throw new IllegalArgumentException(
							"Sync complete methods should use McpSyncRequestContext instead of McpAsyncRequestContext parameter: "
									+ 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());

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Remove the duplicate context parameter, keeping exactly one McpSyncRequestContext.
  2. If you need async behavior, remove the sync context entirely and use a single McpAsyncRequestContext with a reactive return type.
  3. Re-check the full parameter list after refactoring to confirm only one context parameter remains.

Example fix

// before
@McpPrompt(name = "p")
public String complete(String q, McpSyncRequestContext c1, McpSyncRequestContext c2) { ... }
// after
@McpPrompt(name = "p")
public String complete(String q, McpSyncRequestContext context) { ... }
Defensive patterns

Strategy: validation

Validate before calling

long ctxParams = Arrays.stream(method.getParameters())
    .filter(p -> McpSyncRequestContext.class.isAssignableFrom(p.getType())
              || McpAsyncRequestContext.class.isAssignableFrom(p.getType())).count();
if (ctxParams > 1) throw new IllegalStateException("Only one request context parameter allowed");

Try / catch

try { registry.register(bean); } catch (IllegalArgumentException e) { log.error("Invalid @McpPrompt signature: {}", e.getMessage()); }

Prevention

When it happens

Trigger: An @McpPrompt method declaring two context parameters, e.g. complete(String q, McpSyncRequestContext c1, McpSyncRequestContext c2), or mixing McpSyncRequestContext with McpAsyncRequestContext.

Common situations: Copy-paste duplication of a context parameter; refactoring from sync to async by adding the async context without removing the sync one; confusion over which context type the framework injects.

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


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