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

  1. Inspect the exception's cause/content message to see the server-side error text and fix the arguments passed to the tool
  2. 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
  3. Check MCP server logs; the error content often originates from a server-side exception
  4. 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

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


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/62f32a06ff9a4d09. Report an issue: GitHub.