{"record":{"id":"fea800037d7951f2","repo":"spring-projects/spring-ai","slug":"multiple-sampling-methods-found-count-fea800","errorCode":null,"errorMessage":"Multiple sampling methods found: <count>","messagePattern":"Multiple sampling methods found: <count>","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/sampling/SyncMcpSamplingProvider.java","lineNumber":116,"sourceCode":"\t\t\t\t\tFunction<CreateMessageRequest, CreateMessageResult> methodCallback = SyncMcpSamplingMethodCallback\n\t\t\t\t\t\t.builder()\n\t\t\t\t\t\t.method(mcpSamplingMethod)\n\t\t\t\t\t\t.bean(samplingObject)\n\t\t\t\t\t\t.sampling(samplingAnnotation)\n\t\t\t\t\t\t.build();\n\n\t\t\t\t\treturn new SyncSamplingSpecification(samplingAnnotation.clients(), methodCallback);\n\t\t\t\t})\n\t\t\t\t.toList())\n\t\t\t.flatMap(List::stream)\n\t\t\t.toList();\n\n\t\tif (samplingHandlers.isEmpty()) {\n\t\t\tlogger.warn(\"No sampling methods found\");\n\t\t}\n\t\tif (samplingHandlers.size() > 1) {\n\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\tlogger.warn(\"Multiple sampling methods found: \" + samplingHandlers.size());\n\t\t\t}\n\t\t}\n\n\t\treturn samplingHandlers;\n\t}\n\n\t/**\n\t * Returns the methods of the given bean class.\n\t * @param bean the bean instance\n\t * @return the methods of the bean class\n\t */\n\tprotected Method[] doGetClassMethods(Object bean) {\n\t\treturn bean.getClass().getDeclaredMethods();\n\t}\n\n}\n","sourceCodeStart":98,"sourceCodeEnd":133,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/sampling/SyncMcpSamplingProvider.java#L98-L133","documentation":"SyncMcpSamplingProvider.getSamplingSpecifications logs 'Multiple sampling methods found: N' when more than one @McpSampling-annotated method is found in the configured objects. Because MCP sampling typically maps to a single handler per provider, multiple handlers can be ambiguous and only part of them may be honored downstream.","triggerScenarios":"samplingHandlers.size() > 1 after scanning the objects passed to SyncMcpSamplingProvider — i.e. two or more public @McpSampling methods exist — triggering the warn at SyncMcpSamplingProvider.java:116.","commonSituations":"Duplicate handler methods after copy-paste; multiple sampling beans aggregated into one provider; leftover experimental sampling method still annotated.","solutions":["Consolidate to a single @McpSampling-annotated method across the registered objects.","Delete or de-annotate duplicate sampling methods.","If multiple handlers are deliberate, register them through separate providers or verify the server layer supports multiple."],"exampleFix":"// before\n@McpSampling String a(...) {...}\n@McpSampling String b(...) {...}\n// after\n@McpSampling String handle(...) { /* dispatch internally if needed */ }","handlingStrategy":"validation","validationCode":"// Detect duplicates before building the sync provider:\nList<Method> handlers = Arrays.stream(samplingObjects)\n    .flatMap(o -> Arrays.stream(o.getClass().getDeclaredMethods()))\n    .filter(m -> m.isAnnotationPresent(McpSampling.class))\n    .toList();\nif (handlers.size() > 1) throw new IllegalStateException(\"Multiple @McpSampling methods: \" + handlers);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One @McpSampling method per sampling provider instance.","Delete superseded sampling methods rather than leaving them annotated.","Review provider wiring in configuration reviews.","Fail fast in tests when the warning count for this message is non-zero."],"tags":["mcp","annotation-scanning","sampling","duplicate-handlers"],"backgroundTag":"conflicting-config-options","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"}