spring-projects/spring-ai · error · IllegalArgumentException
Method must return either CompleteResult, CompleteCompletion
Error message
Method must return either CompleteResult, CompleteCompletion, List<String>, or String:
What it means
SyncStatelessMcpCompleteMethodCallback.validateReturnType throws this IllegalArgumentException at registration when a @McpComplete method's declared return type is not CompleteResult, CompleteCompletion, List, or String. This startup-time validation prevents invalid handlers from ever being registered on the server.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/complete/SyncStatelessMcpCompleteMethodCallback.java:139
throw new IllegalArgumentException("Unsupported return type: " + result.getClass().getName());
}
/**
* Validates that the method return type is compatible with the complete 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();
boolean validReturnType = CompleteResult.class.isAssignableFrom(returnType)
|| CompleteCompletion.class.isAssignableFrom(returnType) || List.class.isAssignableFrom(returnType)
|| String.class.isAssignableFrom(returnType);
if (!validReturnType) {
throw new IllegalArgumentException(
"Method must return either CompleteResult, CompleteCompletion, List<String>, " + "or String: "
+ method.getName() + " in " + method.getDeclaringClass().getName() + " returns "
+ returnType.getName());
}
}
@Override
protected McpTransportContext resolveTransportContext(Object context) {
if (context instanceof McpTransportContext c) {
return c;
}
return null;
}
/**
* Checks if a parameter type is compatible with the exchange type.
* @param paramType The parameter type to check
* @return true if the parameter type is compatible with the exchange type, falseView on GitHub (pinned to 98a7beda4f)
Solutions
- Change the return type to CompleteResult, CompleteCompletion, List<String>, or String
- Create a dedicated @McpComplete method that adapts the existing method's output
- Verify imports so List/String resolve to java.util.List / java.lang.String
Example fix
// before
@McpComplete(promptName = "p")
public void complete(String v) { }
// after
@McpComplete(promptName = "p")
public List<String> complete(String v) { return List.of(); } Defensive patterns
Strategy: validation
Validate before calling
Class<?> rt = method.getReturnType();
if (!(CompleteResult.class.isAssignableFrom(rt) || CompleteCompletion.class.isAssignableFrom(rt)
|| List.class.isAssignableFrom(rt) || String.class.isAssignableFrom(rt)))
throw new IllegalStateException("@McpComplete method must return CompleteResult/CompleteCompletion/List<String>/String"); Type guard
static boolean isCompleteCompatible(Method m) {
Class<?> rt = m.getReturnType();
return CompleteResult.class.isAssignableFrom(rt) || CompleteCompletion.class.isAssignableFrom(rt)
|| List.class.isAssignableFrom(rt) || String.class.isAssignableFrom(rt);
} Try / catch
try { registry.register(statelessCallback); }
catch (IllegalArgumentException e) { log.error("invalid @McpComplete signature: {}", e.getMessage()); throw new BeanInitializationException(e.getMessage(), e); } Prevention
- Validate return types in a startup test that scans all @McpComplete methods
- Never return void or custom DTOs from completion handlers
- Keep imports correct (java.util.List)
When it happens
Trigger: Annotating a method returning void, Map, custom DTO, or array with @McpComplete and building the SyncStatelessMcpCompleteMethodCallback during annotation scanning.
Common situations: Reusing a tool method as a completion handler without changing its signature, or a refactoring that changed the return type after registration code was written.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Method must return either CompleteResult, CompleteCompletion
- Method must have void or Mono<Void> return type:
- Method must have void return type: " + method.getName() + "
- Method must have void return type:
- Either prompt or uri must be provided!
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/cf397e2b5ed4e950.
Report an issue: GitHub.