{"record":{"id":"295c3cd12e744981","repo":"spring-projects/spring-ai","slug":"method-must-have-exactly-1-parameter-list-mcpsche-295c3c","errorCode":null,"errorMessage":"Method must have exactly 1 parameter (List<McpSchema.Resource>): ","messagePattern":"Method must have exactly 1 parameter \\(List<McpSchema\\.Resource>\\): ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/resource/AbstractMcpResourceListChangedMethodCallback.java","lineNumber":95,"sourceCode":"\t * Validates that the method return type is compatible with the resource list changed\n\t * consumer callback. This method should be implemented by subclasses to handle\n\t * specific return type validation.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the return type is not compatible\n\t */\n\tprotected abstract void validateReturnType(Method method);\n\n\t/**\n\t * Validates method parameters. This method provides common validation logic.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the parameters are not compatible\n\t */\n\tprotected void validateParameters(Method method) {\n\t\tParameter[] parameters = method.getParameters();\n\n\t\t// Check parameter count - must have exactly 1 parameter\n\t\tif (parameters.length != 1) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Method must have exactly 1 parameter (List<McpSchema.Resource>): \" + method.getName() + \" in \"\n\t\t\t\t\t\t\t+ method.getDeclaringClass().getName() + \" has \" + parameters.length + \" parameters\");\n\t\t}\n\n\t\t// Check parameter type - must be List<McpSchema.Resource>\n\t\tClass<?> paramType = parameters[0].getType();\n\t\tif (!List.class.isAssignableFrom(paramType)) {\n\t\t\tthrow new IllegalArgumentException(\"Parameter must be of type List<McpSchema.Resource>: \" + method.getName()\n\t\t\t\t\t+ \" in \" + method.getDeclaringClass().getName() + \" has parameter of type \" + paramType.getName());\n\t\t}\n\t}\n\n\t/**\n\t * Builds the arguments array for invoking the method.\n\t * <p>\n\t * This method constructs an array of arguments based on the method's parameter types\n\t * and the available values.\n\t * @param method The method to build arguments for","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/changed/resource/AbstractMcpResourceListChangedMethodCallback.java#L77-L113","documentation":"The Spring AI MCP resource-list-changed callback registration validates that the annotated consumer method takes exactly one parameter of type List<McpSchema.Resource>. This error is thrown when the method's parameter count differs from 1. The message includes the method name, declaring class, and actual parameter count to pinpoint the offending method.","triggerScenarios":"Registering an @McpResourceListChanged (async/sync) callback method whose signature has 0 parameters or 2+ parameters; validateParameters is invoked during builder construction via validateMethod.","commonSituations":"Developers write consumer methods with no arguments expecting a push notification, or add extra parameters like a client id or McpSyncServer alongside the resource list, mirroring other MCP callback styles.","solutions":["Change the callback method to accept exactly one parameter of type List<McpSchema.Resource>.","Remove any extra parameters (e.g. server references, client names) from the method signature.","If no resource data is needed, still declare the single List<McpSchema.Resource> parameter and ignore it."],"exampleFix":"// before\npublic void onResourcesChanged() { ... }\n// after\npublic void onResourcesChanged(List<McpSchema.Resource> updatedResources) { ... }","handlingStrategy":"validation","validationCode":"Method m = bean.getClass().getMethod(\"onResourcesChanged\", List.class);\nif (m.getParameterCount() != 1) throw new IllegalStateException(\"callback must take exactly one List<McpSchema.Resource>\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the exact signature: void name(List<McpSchema.Resource> resources).","Copy signatures from the library's test/example classes.","Rely on annotation-driven registration rather than manual Method wiring."],"tags":["java","mcp","method-signature","validation"],"backgroundTag":"missing-required-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"}