spring-projects/spring-ai · error · ToolExecutionException
Error calling tool:
Error message
Error calling tool:
What it means
AsyncMcpToolCallback.call() wraps any error reported by the remote MCP server's tool response into a ToolExecutionException. The MCP protocol lets a tool return a successful response whose isError flag is set with the error message in content(); the library surfaces that server-side failure to the caller rather than returning the content as a normal result. The message text after the prefix is the server-provided error content.
Source
Thrown at mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallback.java:155
}).contextWrite(ctx -> ctx.putAll(ToolCallReactiveContextHolder.getContext())).block();
}
catch (McpError ex) {
logger.error("Protocol error while calling tool: ", ex);
// Since the tool calling manager only handles ToolExecutionException, this
// bubbles up and fails the model interaction.
throw ex;
}
catch (Exception ex) {
logger.error("Exception while tool calling: ", ex);
throw new ToolExecutionException(this.getToolDefinition(), ex);
}
Assert.notNull(response, "response was null");
if (response.isError() != null && response.isError()) {
if (logger.isErrorEnabled()) {
logger.error("Error calling tool: " + response.content());
}
throw new ToolExecutionException(this.getToolDefinition(),
new IllegalStateException("Error calling tool: " + response.content()));
}
return jsonHelper.toJson(response.content());
}
/**
* Creates a builder for constructing AsyncMcpToolCallback instances.
* @return a new builder
*/
public static Builder builder() {
return new Builder();
}
/**
* Builder for constructing AsyncMcpToolCallback instances.
*/
public static final class Builder {
View on GitHub (pinned to 98a7beda4f)
Solutions
- Inspect the exception's cause/content message to see the server-side error text and fix the arguments passed to the tool
- Verify the tool name and its input schema against the current MCP server (list tools) — the server may have been upgraded or the tool removed
- Check MCP server logs; the error content often originates from a server-side exception
- Retry with corrected input; if the server is misbehaving, restart or fix the MCP server tool
Example fix
// before
callback.call("{\"city\": \"" + userInput + "\"}", null);
// after
// validate input against the tool's schema and handle the protocol error
definition = callback.getToolDefinition();
try {
return callback.call(jsonSchemaValidate(definition.inputSchema(), userInputJson), null);
} catch (ToolExecutionException e) {
log.error("MCP tool {} rejected the call: {}", definition.name(), e.getCause().getMessage());
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
ToolDefinition def = callback.getToolDefinition(); JsonSchemaValidator.validateOrThrow(def.inputSchema(), argumentsJson); // pre-validate input against the advertised schema
Type guard
boolean isErrorResult(CallToolResult r) { return r != null && Boolean.TRUE.equals(r.isError()); } Try / catch
try {
String out = asyncToolCallback.call(inputJson, toolContext);
} catch (ToolExecutionException e) {
logger.warn("MCP tool {} failed: {}", e.getToolDefinition().name(), e.getCause().getMessage());
// surface to user or fall back
} Prevention
- Validate tool arguments against the tool's inputSchema before calling
- Re-fetch tool definitions when the MCP server version changes
- Log the server error content from the cause to speed diagnosis
- Add timeouts so a misbehaving server cannot hang the call
When it happens
Trigger: Calling an async MCP tool via AsyncMcpToolCallback.call(String, ToolContext) where the McpAsyncClient's CallToolResult has isError()==true — i.e. the remote tool executed but returned a protocol-level error (bad tool input, tool-internal exception, missing tool on server).
Common situations: MCP server tool validates arguments and rejects them; the tool implementation on the server throws and the server returns the exception message as error content; calling a tool name that no longer exists on the server after a server upgrade; passing arguments that fail the server tool's JSON schema.
Related errors
- Error calling tool:
- Failed to read stdio connection resource
- SSE connection '<connectionName>' requires a 'url' property.
- Failed to create SSE transport for connection '<connectionNa
- Multiple tools with the same name (%s)
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/62f32a06ff9a4d09.
Report an issue: GitHub.