spring-projects/spring-ai · error · McpElicitationMethodException
Error invoking elicitation method:
Error message
Error invoking elicitation method:
What it means
SyncMcpElicitationMethodCallback.apply() wraps any exception thrown while reflectively invoking a @McpElicitation-annotated method into an McpElicitationMethodException. The original cause (e.g. a user-code NPE or return-type mismatch) is preserved as the cause. It signals that the elicitation callback method itself failed during execution, not that the MCP protocol exchange failed.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/elicitation/SyncMcpElicitationMethodCallback.java:98
.build();
}
else if (this.method.getReturnType().isAssignableFrom(ElicitResult.class)) {
// If the method returns ElicitResult, return it directly
return (ElicitResult) result;
}
else {
// TODO add support for methods returning simple types or Objects of
// elicitation schema type.
throw new IllegalStateException("Method must return ElicitResult or StructuredElicitResult: "
+ this.method.getName() + " in " + this.method.getDeclaringClass().getName() + " returns "
+ this.method.getReturnType().getName());
}
}
catch (Exception e) {
throw new McpElicitationMethodException("Error invoking elicitation method: " + this.method.getName(), e);
}
}
/**
* Validates that the method return type is compatible with the elicitation callback.
* @param method The method to validate
* @throws IllegalArgumentException if the return type is not compatible
*/
@Override
protected void validateReturnType(Method method) {
Class<?> returnType = method.getReturnType();
if (!ElicitResult.class.isAssignableFrom(returnType)
&& !StructuredElicitResult.class.isAssignableFrom(returnType)) {
throw new IllegalArgumentException("Method must return ElicitResult: " + method.getName() + " in "
+ method.getDeclaringClass().getName() + " returns " + returnType.getName());
}
}View on GitHub (pinned to 98a7beda4f)
Solutions
- Inspect the cause chain (getCause()) of the McpElicitationMethodException to find the real failure in your handler method
- Ensure the annotated method's return type is ElicitResult or StructuredElicitResult
- Add null/argument checks inside your elicitation handler before using the request
- Fix visibility of the annotated method (must be accessible for reflection)
Example fix
// before
@McpElicitation(clients = "client1")
public String askUser(ElicitRequest request) { return request.message(); }
// after
@McpElicitation(clients = "client1")
public ElicitResult askUser(ElicitRequest request) {
if (request == null) { throw new IllegalArgumentException("request required"); }
return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of());
} Defensive patterns
Strategy: try-catch
Validate before calling
for (Method m : handler.getClass().getDeclaredMethods()) {
if (m.isAnnotationPresent(McpElicitation.class)
&& !ElicitResult.class.isAssignableFrom(m.getReturnType())
&& !StructuredElicitResult.class.isAssignableFrom(m.getReturnType())) {
throw new IllegalStateException(m.getName() + " must return ElicitResult or StructuredElicitResult");
}
} Try / catch
try {
elicitationCallback.apply(exchange, request);
} catch (McpElicitationMethodException e) {
logger.error("elicitation handler failed", e.getCause());
return new ElicitResult(ElicitResult.Action.DENY, Map.of());
} Prevention
- Keep handler bodies minimal and null-check the request argument first
- Always return ElicitResult/StructuredElicitResult from @McpElicitation methods
- Add a startup self-test that invokes each handler with a sample request
When it happens
Trigger: Registering a @McpElicitation handler method whose body throws at runtime; the method returns a type other than ElicitResult/StructuredElicitResult; reflection on the method fails (IllegalAccessException).
Common situations: User handler code dereferences a null request argument; an annotated method with the wrong return type slipped past compile-time checks (e.g. raw types); tests like testNullRequest pass a null request and the handler throws.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Currently only methods with a single ElicitRequest parameter
- Error invoking resource list changed consumer method: " + th
- Error invoking tool list changed consumer method:
- Method must not be null
- Error invoking complete method:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/a0e883a8bc0640f7.
Report an issue: GitHub.