{"record":{"id":"be864f22a7aad1f0","repo":"spring-projects/spring-ai","slug":"method-cannot-have-more-than-one-request-context-p","errorCode":null,"errorMessage":"Method cannot have more than one request context parameter: {method} in {class}","messagePattern":"Method cannot have more than one request context parameter: (.+?) in (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/AbstractMcpCompleteMethodCallback.java","lineNumber":202,"sourceCode":"\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\n\t\t\t\thasProgressTokenParam = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Skip McpMeta parameters from validation\n\t\t\tif (McpMeta.class.isAssignableFrom(paramType)) {\n\t\t\t\tif (hasMetaParam) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one McpMeta parameter: \"\n\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\n\t\t\t\thasMetaParam = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (McpSyncRequestContext.class.isAssignableFrom(paramType)) {\n\t\t\t\tif (hasRequestContextParam) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one request context parameter: \"\n\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\n\t\t\t\tif (McpPredicates.isReactiveReturnType.test(method)) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Async complete methods should use McpAsyncRequestContext instead of McpSyncRequestContext parameter: \"\n\t\t\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\n\n\t\t\t\thasRequestContextParam = true;\n\t\t\t}\n\t\t\telse if (McpAsyncRequestContext.class.isAssignableFrom(paramType)) {\n\t\t\t\tif (hasRequestContextParam) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one request context parameter: \"\n\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\n\t\t\t\tif (McpPredicates.isNotReactiveReturnType.test(method)) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Sync complete methods should use McpSyncRequestContext instead of McpAsyncRequestContext parameter: \"","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/AbstractMcpCompleteMethodCallback.java#L184-L220","documentation":"Only one McpSyncRequestContext parameter is permitted per completion method; the framework injects the request context once. validateParameters() throws this IllegalArgumentException when a second McpSyncRequestContext-typed parameter is detected (message names the method and class).","triggerScenarios":"Declaring two McpSyncRequestContext parameters on a single @McpComplete-annotated method and registering it.","commonSituations":"Duplicated context parameter after refactoring or merging branches; misunderstanding that the context aggregates request state so one instance suffices.","solutions":["Keep exactly one McpSyncRequestContext parameter and remove the duplicate.","Access all request data (arguments, progress, logging) through the single context instance.","If using a reactive return type, replace McpSyncRequestContext with McpAsyncRequestContext (see the companion async error)."],"exampleFix":"// before\npublic void complete(String value, McpSyncRequestContext ctx1, McpSyncRequestContext ctx2) { }\n// after\npublic void complete(String value, McpSyncRequestContext ctx) { }","handlingStrategy":"validation","validationCode":"long ctxs = Arrays.stream(method.getParameters())\n    .filter(p -> McpSyncRequestContext.class.isAssignableFrom(p.getType())).count();\nif (ctxs > 1) throw new IllegalStateException(\"duplicate request context parameter in \" + method.getName());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare the request context parameter at most once.","Use McpAsyncRequestContext for reactive return types.","Read all request state from the single context instance."],"tags":["mcp","validation","duplicate-parameter","completion"],"backgroundTag":"invalid-argument-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}