{"record":{"id":"40549754315f5219","repo":"spring-projects/spring-ai","slug":"method-cannot-have-more-than-one-mcpmeta-parameter-405497","errorCode":null,"errorMessage":"Method cannot have more than one McpMeta parameter: ${method} in ${declaringClass}","messagePattern":"Method cannot have more than one McpMeta 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":236,"sourceCode":"\t\t\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\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\"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\t\t\t\thasRequestContextParam = true;\n\t\t\t}\n\t\t\telse if (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}\n\t\t\telse if (isExchangeOrContextType(paramType)) {\n\t\t\t\tif (hasExchangeParam) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Method cannot have more than one exchange parameter: \"\n\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}\n\t\t\t\thasExchangeParam = true;\n\t\t\t}\n\t\t\telse if (ReadResourceRequest.class.isAssignableFrom(paramType)\n\t\t\t\t\t|| String.class.isAssignableFrom(paramType)) {\n\t\t\t\tif (hasRequestOrUriParam) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Method cannot have more than one ReadResourceRequest or String parameter: \"\n\t\t\t\t\t\t\t\t\t+ method.getName() + \" in \" + method.getDeclaringClass().getName());\n\t\t\t\t}","sourceCodeStart":218,"sourceCodeEnd":254,"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#L218-L254","documentation":"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.","triggerScenarios":"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.","commonSituations":"Accidentally duplicating McpMeta when merging parameters from two handler methods; copy-paste of a signature block; IDE auto-complete adding a second meta param.","solutions":["Remove one of the McpMeta parameters, keeping exactly one","If extra data is needed, bundle it in a custom object or read from the single McpMeta"],"exampleFix":"// before\npublic String read(String uri, McpMeta meta1, McpMeta meta2) { ... }\n// after\npublic String read(String uri, McpMeta meta) { ... }","handlingStrategy":"validation","validationCode":"long metaCount = Arrays.stream(method.getParameterTypes())\n    .filter(McpMeta.class::isAssignableFrom).count();\nif (metaCount > 1) throw new IllegalStateException(method + \" declares \" + metaCount + \" McpMeta parameters\");","typeGuard":null,"tryCatchPattern":"try { provider.build(...); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"more than one McpMeta parameter\")) { /* deduplicate McpMeta params */ }\n  else throw e;\n}","preventionTips":["Declare at most one McpMeta parameter per handler","Review method signatures after copy-paste or merge operations"],"tags":["mcp","spring-ai","duplicate-parameter"],"backgroundTag":"invalid-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}