spring-projects/spring-ai · info
Multiple elicitation methods found
Error message
Multiple elicitation methods found: <count>
What it means
AsyncMcpElicitationProvider expects at most one elicitation handler among the supplied objects; MCP elicitation is a single server-level capability, not a list of providers. When it finds more than one @McpElicitation-annotated method it logs this warning reporting the count, but still proceeds (the handlers are returned). The warning flags ambiguous configuration that the library does not treat as fatal.
Solutions
- Keep exactly one @McpElicitation-annotated method across all objects passed to the provider and delete or un-annotate the rest
- If you genuinely need multiple behaviors, gate them inside the single handler method rather than registering several handlers
- Check which beans are auto-scanned into the provider list and exclude duplicates
Example fix
// before
class A { @McpElicitation Mono<ElicitResult> h1(ElicitRequest r) {...} }
class B { @McpElicitation Mono<ElicitResult> h2(ElicitRequest r) {...} }
new AsyncMcpElicitationProvider(List.of(new A(), new B()));
// after
class A { @McpElicitation Mono<ElicitResult> handle(ElicitRequest r) { /* route internally */ } }
new AsyncMcpElicitationProvider(List.of(new A())); Defensive patterns
Strategy: validation
Validate before calling
long count = beans.stream()
.flatMapToLong(b -> Arrays.stream(b.getClass().getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(McpElicitation.class)))
.count();
if (count > 1) throw new IllegalStateException("Multiple @McpElicitation handlers: " + count); Type guard
static boolean hasSingleElicitationHandler(List<Object> beans) {
return beans.stream()
.flatMap(b -> Arrays.stream(b.getClass().getDeclaredMethods()))
.filter(m -> m.isAnnotationPresent(McpElicitation.class))
.count() == 1;
} Prevention
- Keep a single elicitation handler across the whole application
- Audit component-scanned beans for stray @McpElicitation annotations after refactors or merges
When it happens
Trigger: getElicitationSpecifications() collects more than one method annotated @McpElicitation across the provider objects (elicitationHandlers.size() > 1), e.g. two beans each with an elicitation handler or duplicate annotation on multiple methods in one class.
Common situations: Registering multiple elicitation service beans after a refactor; copying an example handler and leaving both in the classpath-scanned configuration; mixing legacy and new handler methods during migration.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Multiple elicitation methods found
- No elicitation methods found
- No elicitation methods found
- No complete methods found in the provided complete objects
- No prompt methods found in the provided prompt objects
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/a8032c0a87461d19.
Report an issue: GitHub.
Appendix: source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/elicitation/AsyncMcpElicitationProvider.java:116
Function<ElicitRequest, Mono<ElicitResult>> methodCallback = AsyncMcpElicitationMethodCallback
.builder()
.method(mcpElicitationMethod)
.bean(elicitationObject)
.elicitation(elicitationAnnotation)
.build();
return new AsyncElicitationSpecification(elicitationAnnotation.clients(), methodCallback);
})
.toList())
.flatMap(List::stream)
.toList();
if (elicitationHandlers.isEmpty()) {
logger.warn("No elicitation methods found");
}
if (elicitationHandlers.size() > 1) {
if (logger.isWarnEnabled()) {
logger.warn("Multiple elicitation methods found: " + elicitationHandlers.size());
}
}
return elicitationHandlers;
}
/**
* 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)