{"record":{"id":"7935d586f9d0d7e9","repo":"spring-projects/spring-ai","slug":"no-elicitation-methods-found","errorCode":null,"errorMessage":"No elicitation methods found","messagePattern":"No elicitation methods found","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":112,"sourceCode":"\t\t\t\t.sorted((m1, m2) -> m1.getName().compareTo(m2.getName()))\n\t\t\t\t.map(mcpElicitationMethod -> {\n\t\t\t\t\tvar elicitationAnnotation = mcpElicitationMethod.getAnnotation(McpElicitation.class);\n\n\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}","sourceCodeStart":94,"sourceCodeEnd":130,"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#L94-L130","documentation":"AsyncMcpElicitationProvider scans its provider objects for methods annotated with @McpElicitation and adapts them into elicitation handler specifications. If the collected handler list is empty it logs this warning. It is not an exception: the server just has no elicitation handler registered. The library logs it to flag that elicitation objects were supplied yet yielded no methods matching the expected annotation and async signature.","triggerScenarios":"getElicitationSpecifications() returns an empty list because no method in the supplied objects is annotated @McpElicitation (or none survives the reactive/async-signature predicates), or no objects were passed at all.","commonSituations":"Forgetting to annotate the elicitation handler method; annotating a sync handler and passing it to the async provider; methods defined on a parent class (getDeclaredMethods only); client registers elicitation support but the server-side bean was never wired into the provider.","solutions":["Annotate exactly one method with @McpElicitation in the object(s) passed to AsyncMcpElicitationProvider, using the async (Mono/Flux-based) signature this provider expects","Ensure the handler method is declared on the bean's own class, not a superclass or interface","Use SyncMcpElicitationProvider instead if your handler is synchronous","If elicitation is not used, remove the elicitation provider/objects from configuration to avoid the warning"],"exampleFix":"// before\nclass MyElicitation { public ElicitResult askUser(String msg) { ... } } // not annotated / sync\n\n// after\nclass MyElicitation {\n    @McpElicitation\n    public Mono<ElicitResult> askUser(ElicitRequest request) { ... }\n}\nnew AsyncMcpElicitationProvider(List.of(new MyElicitation()));","handlingStrategy":"validation","validationCode":"long found = Arrays.stream(bean.getClass().getDeclaredMethods())\n    .filter(m -> m.isAnnotationPresent(McpElicitation.class))\n    .count();\nif (found == 0) throw new IllegalStateException(\"No @McpElicitation handler in \" + bean.getClass());","typeGuard":"static boolean hasElicitationHandler(Object bean) {\n    return Arrays.stream(bean.getClass().getDeclaredMethods())\n        .anyMatch(m -> m.isAnnotationPresent(McpElicitation.class));\n}","tryCatchPattern":null,"preventionTips":["Register exactly one elicitation handler bean for the async provider","Use the sync provider for synchronous handlers and the async provider for Mono/Flux handlers","Add a startup assertion that elicitation specifications are non-empty when elicitation is required"],"tags":["mcp","spring-ai","annotation-scanning","elicitation"],"backgroundTag":"empty-result-set","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"}