alibaba/spring-ai-alibaba · warning · ToolCancelledException
Tool execution was cancelled
Error message
Tool execution was cancelled
What it means
When the async tool's future completes with a CancellationException (e.g. the CancellationToken was triggered), call() throws ToolCancelledException with message "Tool execution was cancelled". This is a typed signal that the tool was aborted rather than failed.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tool/AsyncToolCallback.java:111
* @throws ToolCancelledException if the operation was cancelled
*/
@Override
default String call(String arguments, ToolContext context) {
try {
return callAsync(arguments, context).join();
}
catch (CompletionException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException re) {
throw re;
}
if (cause instanceof Error err) {
throw err;
}
throw new RuntimeException("Async tool execution failed", cause);
}
catch (CancellationException e) {
throw new ToolCancelledException("Tool execution was cancelled", e);
}
}
/**
* Returns whether this tool executes asynchronously.
* @return true (always async for this interface)
*/
default boolean isAsync() {
return true;
}
/**
* Returns the timeout duration for this tool execution.
* @return the timeout duration, defaults to 5 minutes
*/
default Duration getTimeout() {
return Duration.ofMinutes(5);
}View on GitHub (pinned to f82da0b50f)
Solutions
- Catch ToolCancelledException specifically and treat it as a normal abort, not an error.
- Ensure cancellation tokens are cancelled intentionally; review timeout/cancel call sites.
- Make tools check CancellationToken periodically so cancellation is honored promptly.
- Log cancellation at info/debug level instead of treating it as a failure.
Example fix
// before
try { result = asyncTool.call(input, token); }
catch (RuntimeException e) { log.error("tool failed", e); }
// after
try { result = asyncTool.call(input, token); }
catch (ToolCancelledException e) { log.info("tool cancelled, aborting gracefully"); return null; }
catch (RuntimeException e) { log.error("tool failed", e); } Defensive patterns
Strategy: try-catch
Try / catch
try { result = callback.call(input, token); } catch (ToolCancelledException e) { /* graceful abort */ } catch (CancellationException e) { /* already wrapped, unreachable but safe */ } Prevention
- Treat cancellation as control flow, not failure
- Wire CancellationToken through all long-running tools
- Check token status before merging results
- Log cancellations at info level
When it happens
Trigger: A CancellationToken passed to the async tool is cancelled while the tool is still running; the underlying future is cancelled() by timeout or upstream abort; the executor cancels the task.
Common situations: User aborts a request mid-tool-call, agent-level timeouts cancelling running tools, cancellation propagation when a graph node is interrupted.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- Async tool execution failed
- Tool execution was cancelled
- TOOL_PARAMS_MISSING
- TOOL_EXECUTION_ERROR
- BUILD_TOOL_RESULT_ERROR
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/7df2f18294199a96.
Report an issue: GitHub.