{"record":{"id":"0bd097e4625fcaf7","repo":"spring-projects/spring-ai","slug":"method-cannot-have-more-than-one-readresourcereque-0bd097","errorCode":null,"errorMessage":"Method cannot have more than one ReadResourceRequest parameter: ${method} in ${declaringClass}","messagePattern":"Method cannot have more than one ReadResourceRequest parameter: (.+?) in (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java","lineNumber":347,"sourceCode":"\t\t\t\t\tif (McpPredicates.isNotReactiveReturnType.test(method)) {\n\t\t\t\t\t\tthrow new IllegalArgumentException(\n\t\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\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t\t}\n\t\t\t\t\thasRequestContextParam = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check if we have more than one exchange parameter\n\t\tif (exchangeParamCount > 1) {\n\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one exchange parameter: \"\n\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t}\n\n\t\t// Check if we have more than one request parameter\n\t\tif (requestParamCount > 1) {\n\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one ReadResourceRequest parameter: \"\n\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t}\n\n\t\t// Check if we have more than one meta parameter\n\t\tif (metaParamCount > 1) {\n\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one McpMeta parameter: \" + method.getName()\n\t\t\t\t\t+ \" in \" + method.getDeclaringClass().getName());\n\t\t}\n\n\t\t// Calculate how many parameters should be for URI variables\n\t\tint requestContextParamCount = hasRequestContextParam ? 1 : 0;\n\t\tint specialParamCount = exchangeParamCount + requestParamCount + progressTokenParamCount + metaParamCount\n\t\t\t\t+ requestContextParamCount;\n\t\tint uriVarParamCount = parameters.length - specialParamCount;\n\n\t\t// Check if we have the right number of parameters for URI variables\n\t\tif (uriVarParamCount != this.uriVariables.size()) {\n\t\t\tthrow new IllegalArgumentException(","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/resource/AbstractMcpResourceMethodCallback.java#L329-L365","documentation":"Thrown when an @McpResource method with URI variables declares more than one ReadResourceRequest parameter. Only a single request parameter can be bound, so the framework rejects the method at registration time.","triggerScenarios":"Declaring two ReadResourceRequest parameters (e.g. ReadResourceRequest request, ReadResourceRequest req2) on an @McpResource method whose URI has variables; validateParametersWithUriVariables throws when requestParamCount > 1.","commonSituations":"Copy-paste of the request parameter; thinking an extra request param is needed for each URI variable; refactoring residue from merging handlers.","solutions":["Remove the duplicate ReadResourceRequest parameter and keep exactly one","Bind each URI variable with its own String parameter instead of extra request parameters","Access additional data through the single request object (e.g. request.meta())"],"exampleFix":"// before\npublic String read(ReadResourceRequest req, ReadResourceRequest req2) { ... }\n// after\npublic String read(ReadResourceRequest req) { ... }","handlingStrategy":"validation","validationCode":"long reqParams = Arrays.stream(m.getParameters()).filter(p -> ReadResourceRequest.class.isAssignableFrom(p.getType())).count();\nif (reqParams > 1) throw new IllegalStateException(m + \" declares multiple ReadResourceRequest parameters\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use exactly one ReadResourceRequest parameter per resource method","Avoid copy-pasting handler signatures","Add registration-time tests that cover every @McpResource method"],"tags":["mcp","java","validation","duplicate-parameter"],"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"}