spring-projects/spring-ai · error · IllegalArgumentException
Unsupported exchange type: ${exchangeType} for method: ${met
Error message
Unsupported exchange type: ${exchangeType} for method: ${method} in ${declaringClass} What it means
The final fallback in SyncMcpPromptMethodCallback.assignExchangeType fires when the method's exchange parameter is neither McpTransportContext nor McpSyncServerExchange and the runtime exchange object matches no supported type (or is null). It throws IllegalArgumentException describing the unrecognized exchange type for the method.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/method/prompt/SyncMcpPromptMethodCallback.java:87
return syncServerExchange.transportContext();
}
else if (exchange instanceof McpAsyncServerExchange asyncServerExchange) {
throw new IllegalArgumentException("Unsupported Async exchange type: "
+ asyncServerExchange.getClass().getName() + " for Sync method: " + method.getName() + " in "
+ method.getDeclaringClass().getName());
}
}
else if (McpSyncServerExchange.class.isAssignableFrom(paramType)) {
if (exchange instanceof McpSyncServerExchange syncServerExchange) {
return syncServerExchange;
}
throw new IllegalArgumentException(
"Unsupported exchange type: " + (exchange != null ? exchange.getClass().getName() : "null")
+ " for Sync method: " + method.getName() + " in " + method.getDeclaringClass().getName());
}
throw new IllegalArgumentException(
"Unsupported exchange type: " + (exchange != null ? exchange.getClass().getName() : "null")
+ " for method: " + method.getName() + " in " + method.getDeclaringClass().getName());
}
/**
* Apply the callback to the given exchange and request.
* <p>
* This method builds the arguments for the method call, invokes the method, and
* converts the result to a GetPromptResult.
* @param exchange The server exchange, may be null if the method doesn't require it
* @param request The prompt request, must not be null
* @return The prompt result
* @throws McpError if there is an error invoking the prompt method
* @throws IllegalArgumentException if the request is null
*/
@Override
public GetPromptResult apply(McpSyncServerExchange exchange, GetPromptRequest request) {
if (request == null) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Declare the exchange parameter as McpSyncServerExchange or McpTransportContext
- Pass a supported exchange object when invoking the callback
- Align server and callback types so dispatch supplies the expected exchange
Example fix
// before
public GetPromptResult p(Object exchange, Request req) {...}
// after
public GetPromptResult p(McpSyncServerExchange exchange, Request req) {...} Defensive patterns
Strategy: type-guard
Validate before calling
boolean validParam(Method m) { Class<?>[] ps = m.getParameterTypes(); return Arrays.stream(ps).allMatch(t -> McpSyncServerExchange.class.isAssignableFrom(t) || McpTransportContext.class.isAssignableFrom(t) || !isExchangeLike(t)); } Type guard
boolean supportedExchange(Object e) { return e instanceof McpSyncServerExchange || e instanceof McpTransportContext; } Try / catch
try { r = callback.apply(exchange, req); } catch (IllegalArgumentException e) { log.error("Unsupported exchange type for prompt method: {}", e.getMessage(), e); } Prevention
- Declare exchange parameters only as McpSyncServerExchange or McpTransportContext
- Avoid loosely typed (Object) exchange parameters
- Cover every registered prompt with a dispatch-level test
When it happens
Trigger: Invoking a sync prompt callback whose parameter is not an exchange/context type, or whose runtime exchange is of an unexpected class or null.
Common situations: Hand-written method signatures with unsupported exchange-like parameters; custom transports producing novel exchange objects; internal misuse of the callback API.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported exchange type: {exchange != null ? exchange.getC
- Unsupported exchange type: {exchange != null ? exchange.getC
- Unsupported Sync exchange type: {syncServerExchange.getClass
- Unsupported Async exchange type: {asyncServerExchange.getCla
- Async prompt method must not declare parameter of type: {par
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/702736b1b816a6b1.
Report an issue: GitHub.