{"record":{"id":"e9b1a8d08d314c31","repo":"spring-projects/spring-ai","slug":"multiple-elicitation-methods-found-count-e9b1a8","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/SyncMcpElicitationProvider.java","lineNumber":117,"sourceCode":"\n\t\t\t\t\tFunction<ElicitRequest, ElicitResult> methodCallback = SyncMcpElicitationMethodCallback.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 SyncElicitationSpecification(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":99,"sourceCodeEnd":134,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/elicitation/SyncMcpElicitationProvider.java#L99-L134","documentation":"SyncMcpElicitationProvider allows a single elicitation handler; discovering more than one @McpElicitation-annotated method in the supplied objects triggers this warning with the handler count. Execution continues and all handlers are returned, but the configuration is ambiguous since MCP expects one server-level elicitation handler.","triggerScenarios":"elicitationHandlers.size() > 1 in getElicitationSpecifications(): two or more methods annotated @McpElicitation across the provider's objects (multiple beans, or multiple annotated methods in one bean).","commonSituations":"Duplicate handler beans registered via configuration plus component scanning; leftover test/example handlers; merge conflicts that kept both handler implementations.","solutions":["Un-annotate or remove all but one @McpElicitation method across the registered objects","Consolidate logic into the single surviving handler","Audit the bean list passed to SyncMcpElicitationProvider for duplicate elicitation services"],"exampleFix":"// before\n@Service class H1 { @McpElicitation ElicitResult a(ElicitRequest r){...} }\n@Service class H2 { @McpElicitation ElicitResult b(ElicitRequest r){...} }\n\n// after\n@Service class H1 { @McpElicitation ElicitResult handle(ElicitRequest r){...} }\n// H2's method no longer annotated","handlingStrategy":"validation","validationCode":"long count = beans.stream()\n    .flatMap(b -> Arrays.stream(b.getClass().getDeclaredMethods()))\n    .filter(m -> m.isAnnotationPresent(McpElicitation.class))\n    .count();\nif (count > 1) throw new IllegalStateException(\"Expected 1 elicitation handler, found \" + count);","typeGuard":"static boolean singleSyncElicitationHandler(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":["Maintain one canonical elicitation handler class","Grep the codebase for @McpElicitation during code review to catch duplicates"],"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"}