{"record":{"id":"71172c8050f4461a","repo":"spring-projects/spring-ai","slug":"parameter-must-be-of-type-list-mcpschema-resource","errorCode":null,"errorMessage":"Parameter must be of type List<McpSchema.Resource>: ","messagePattern":"Parameter must be of type 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":103,"sourceCode":"\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\n\t * @param exchange The server exchange\n\t * @param updatedResources The updated list of resources\n\t * @return An array of arguments for the method invocation\n\t */\n\tprotected Object[] buildArgs(Method method, Object exchange, List<McpSchema.Resource> updatedResources) {\n\t\tParameter[] parameters = method.getParameters();\n\t\tObject[] args = new Object[parameters.length];\n","sourceCodeStart":85,"sourceCodeEnd":121,"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#L85-L121","documentation":"The resource-list-changed callback's single parameter must be a List (assignable from java.util.List), intended to carry McpSchema.Resource entries. This error is thrown when the parameter type is something else. The message names the method, class, and the actual parameter type.","triggerScenarios":"Registering a callback method whose sole parameter is not a List, e.g. a single McpSchema.Resource, ResourceReference, String, or a custom DTO; checked in validateParameters during callback building.","commonSituations":"Confusing this callback with resource-read callbacks that receive a single resource; using List<Resource> from a different package (e.g. Spring core.io.Resource) instead of McpSchema.Resource.","solutions":["Change the parameter to List<McpSchema.Resource> (java.util.List of org.springframework.ai.mcp.McpSchema.Resource).","Verify the import: use McpSchema.Resource, not another class named Resource.","If you want per-resource handling, accept the full list and iterate inside the method."],"exampleFix":"// before\npublic void onResourcesChanged(McpSchema.Resource resource) { ... }\n// after\npublic void onResourcesChanged(List<McpSchema.Resource> updatedResources) { ... }","handlingStrategy":"type-guard","validationCode":"Method m = bean.getClass().getMethod(\"onResourcesChanged\", List.class);\nif (!List.class.isAssignableFrom(m.getParameterTypes()[0])) throw new IllegalStateException(\"parameter must be a List\");","typeGuard":"static boolean isValidCallback(Method m) {\n    return m.getParameterCount() == 1 && List.class.isAssignableFrom(m.getParameterTypes()[0]);\n}","tryCatchPattern":null,"preventionTips":["Import org.springframework.ai.mcp.McpSchema.Resource explicitly; avoid ambiguous Resource imports.","Keep callback parameters to List<McpSchema.Resource> only."],"tags":["java","mcp","parameter-type","type-mismatch"],"backgroundTag":"type-mismatch","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"}