{"record":{"id":"a8032c0a87461d19","repo":"spring-projects/spring-ai","slug":"multiple-elicitation-methods-found-count","errorCode":null,"errorMessage":"Multiple elicitation methods found: <count>","messagePattern":"Multiple elicitation methods found: <count>","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/elicitation/AsyncMcpElicitationProvider.java","lineNumber":116,"sourceCode":"\t\t\t\t\tFunction<ElicitRequest, Mono<ElicitResult>> methodCallback = AsyncMcpElicitationMethodCallback\n\t\t\t\t\t\t.builder()\n\t\t\t\t\t\t.method(mcpElicitationMethod)\n\t\t\t\t\t\t.bean(elicitationObject)\n\t\t\t\t\t\t.elicitation(elicitationAnnotation)\n\t\t\t\t\t\t.build();\n\n\t\t\t\t\treturn new AsyncElicitationSpecification(elicitationAnnotation.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 (elicitationHandlers.isEmpty()) {\n\t\t\tlogger.warn(\"No elicitation methods found\");\n\t\t}\n\t\tif (elicitationHandlers.size() > 1) {\n\t\t\tif (logger.isWarnEnabled()) {\n\t\t\t\tlogger.warn(\"Multiple elicitation methods found: \" + elicitationHandlers.size());\n\t\t\t}\n\t\t}\n\n\t\treturn elicitationHandlers;\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/elicitation/AsyncMcpElicitationProvider.java#L98-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nclass A { @McpElicitation Mono<ElicitResult> h1(ElicitRequest r) {...} }\nclass B { @McpElicitation Mono<ElicitResult> h2(ElicitRequest r) {...} }\nnew AsyncMcpElicitationProvider(List.of(new A(), new B()));\n\n// after\nclass A { @McpElicitation Mono<ElicitResult> handle(ElicitRequest r) { /* route internally */ } }\nnew AsyncMcpElicitationProvider(List.of(new A()));","handlingStrategy":"validation","validationCode":"long count = beans.stream()\n    .flatMapToLong(b -> Arrays.stream(b.getClass().getDeclaredMethods())\n        .filter(m -> m.isAnnotationPresent(McpElicitation.class)))\n    .count();\nif (count > 1) throw new IllegalStateException(\"Multiple @McpElicitation handlers: \" + count);","typeGuard":"static boolean hasSingleElicitationHandler(List<Object> beans) {\n    return beans.stream()\n        .flatMap(b -> Arrays.stream(b.getClass().getDeclaredMethods()))\n        .filter(m -> m.isAnnotationPresent(McpElicitation.class))\n        .count() == 1;\n}","tryCatchPattern":null,"preventionTips":["Keep a single elicitation handler across the whole application","Audit component-scanned beans for stray @McpElicitation annotations after refactors or merges"],"tags":["mcp","spring-ai","annotation-scanning","elicitation"],"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"}