{"record":{"id":"589194c99e5535a3","repo":"spring-projects/spring-ai","slug":"method-must-have-at-least-1-parameter-elicitreque","errorCode":null,"errorMessage":"Method must have at least 1 parameter (ElicitRequest): ","messagePattern":"Method must have at least 1 parameter \\(ElicitRequest\\): ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/elicitation/AbstractMcpElicitationMethodCallback.java","lineNumber":93,"sourceCode":"\t * This method should be implemented by subclasses to handle specific return type\n\t * validation.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the return type is not compatible\n\t */\n\tprotected abstract void validateReturnType(Method method);\n\n\t/**\n\t * Validates method parameters. This method provides common validation logic and\n\t * delegates exchange type checking to subclasses.\n\t * @param method The method to validate\n\t * @throws IllegalArgumentException if the parameters are not compatible\n\t */\n\tprotected void validateParameters(Method method) {\n\t\tParameter[] parameters = method.getParameters();\n\n\t\t// Check parameter count - must have at least 1 parameter\n\t\tif (parameters.length < 1) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Method must have at least 1 parameter (ElicitRequest): \" + method.getName() + \" in \"\n\t\t\t\t\t\t\t+ method.getDeclaringClass().getName() + \" has \" + parameters.length + \" parameters\");\n\t\t}\n\n\t\t// Check parameter types\n\t\tif (parameters.length == 1) {\n\t\t\t// Single parameter must be ElicitRequest\n\t\t\tif (!ElicitRequest.class.isAssignableFrom(parameters[0].getType())) {\n\t\t\t\tthrow new IllegalArgumentException(\"Single parameter must be of type ElicitRequest: \" + method.getName()\n\t\t\t\t\t\t+ \" in \" + method.getDeclaringClass().getName() + \" has parameter of type \"\n\t\t\t\t\t\t+ parameters[0].getType().getName());\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// TODO: Support for multiple parameters corresponding to ElicitRequest\n\t\t\t// fields\n\t\t\t// For now, we only support the single parameter version\n\t\t\tthrow new IllegalArgumentException(","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/elicitation/AbstractMcpElicitationMethodCallback.java#L75-L111","documentation":"AbstractMcpElicitationMethodCallback.validateParameters throws this IllegalArgumentException when a method registered for MCP elicitation has zero parameters. An elicitation handler must accept at least an ElicitRequest parameter so the framework can pass the client's response data.","triggerScenarios":"Annotating a no-argument method with @McpElicitation; validateParameters is invoked from validateMethod during callback construction.","commonSituations":"Adding the annotation to an empty callback-style method (e.g. run() or handle()) assuming the framework injects state via fields rather than parameters.","solutions":["Add an ElicitRequest parameter as the first (or only) argument of the method","If extra parameters are needed, follow the supported signatures: (ElicitRequest) or (ElicitRequest, McpTransportContext/McpSyncServerExchange) per the library's parameter rules","Check validateParameters' type checks so the first parameter is exactly ElicitRequest, not Object or a subclass wrapper"],"exampleFix":"// before\n@McpElicitation(elicitId = \"confirm\")\npublic void onConfirm() { }\n// after\n@McpElicitation(elicitId = \"confirm\")\npublic CompleteResult onConfirm(ElicitRequest request) { return ...; }","handlingStrategy":"validation","validationCode":"for (Method m : bean.getClass().getDeclaredMethods()) {\n    if (m.isAnnotationPresent(McpElicitation.class) && m.getParameterCount() < 1)\n        throw new IllegalStateException(\"@McpElicitation method \" + m.getName() + \" needs an ElicitRequest parameter\");\n}","typeGuard":"static boolean hasElicitRequest(Method m) {\n    return m.getParameterCount() > 0 && ElicitRequest.class.isAssignableFrom(m.getParameterTypes()[0]);\n}","tryCatchPattern":"try { new SyncMcpElicitationMethodCallback(bean, method, elicitId); }\ncatch (IllegalArgumentException e) { log.error(\"invalid elicitation signature: {}\", e.getMessage()); throw new BeanInitializationException(e.getMessage(), e); }","preventionTips":["Always declare at least an ElicitRequest parameter on @McpElicitation methods","Put ElicitRequest first if combining with context/exchange parameters","Add a startup test scanning @McpElicitation methods for the required signature"],"tags":["java","mcp","elicitation","parameters","startup-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}