spring-projects/spring-ai · warning
Multiple sampling methods found: <count>
Error message
Multiple sampling methods found: <count>
What it means
AsyncMcpSamplingProvider.getSamplingSpecifictions logs 'Multiple sampling methods found: N' when more than one @McpSampling-annotated method is discovered across the configured objects. Some MCP server wiring expects a single sampling handler, so multiple handlers may be ambiguous or only the first may take effect depending on downstream usage.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/sampling/AsyncMcpSamplingProvider.java:116
Function<CreateMessageRequest, Mono<CreateMessageResult>> methodCallback = AsyncMcpSamplingMethodCallback
.builder()
.method(mcpSamplingMethod)
.bean(samplingObject)
.sampling(samplingAnnotation)
.build();
return new AsyncSamplingSpecification(samplingAnnotation.clients(), methodCallback);
})
.toList())
.flatMap(List::stream)
.toList();
if (samplingHandlers.isEmpty()) {
logger.warn("No sampling methods found");
}
if (samplingHandlers.size() > 1) {
if (logger.isWarnEnabled()) {
logger.warn("Multiple sampling methods found: " + samplingHandlers.size());
}
}
return samplingHandlers;
}
/**
* Returns the methods of the given bean class.
* @param bean the bean instance
* @return the methods of the bean class
*/
protected Method[] doGetClassMethods(Object bean) {
return bean.getClass().getDeclaredMethods();
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Keep exactly one @McpSampling-annotated method across the registered sampling objects, consolidating logic into it.
- Remove stale/duplicate annotated methods or drop their @McpSampling annotation.
- If multiple handlers are intentional, confirm downstream registration supports all of them; otherwise split into separate providers.
Example fix
// before
class Sampler { @McpSampling CompletableFuture<String> a(...) {...} @McpSampling CompletableFuture<String> b(...) {...} }
// after
class Sampler { @McpSampling CompletableFuture<String> handle(...) { /* merged logic */ } } Defensive patterns
Strategy: validation
Validate before calling
// Enforce a single sampling handler before registration:
long count = Arrays.stream(samplingObjects)
.flatMapToLong(o -> Arrays.stream(o.getClass().getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(McpSampling.class)))
.count();
if (count > 1) throw new IllegalStateException("Only one @McpSampling method allowed, found " + count); Prevention
- Keep exactly one @McpSampling method per provider registration.
- Remove leftover experimental sampling methods promptly.
- Add an architecture test banning duplicate @McpSampling annotations across handler classes.
- Route multiple behaviors through one handler method with internal dispatch.
When it happens
Trigger: Two or more public methods annotated with @McpSampling exist across the sampling objects passed to AsyncMcpSamplingProvider; samplingHandlers.size() > 1 triggers the warn at AsyncMcpSamplingProvider.java:116.
Common situations: Accidental duplicate handler methods added during refactoring; multiple sampling classes registered where one combined handler was intended; copy-paste leaving an old sampling method in place alongside the new one.
Related errors
- Multiple sampling methods found: <count>
- No sampling methods found
- No sampling methods found
- Sampling not supported by the client:
- Method must have at least 1 parameter (CreateMessageRequest)
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/276f6579cc2ce210.
Report an issue: GitHub.