alibaba/spring-ai-alibaba · warning · ToolCancelledException
Tool execution was cancelled
Error message
Tool execution was cancelled
What it means
CancellationToken.throwIfCancelled() checks isCancelled() and throws ToolCancelledException with message "Tool execution was cancelled" when a cancellation has been requested. It is the cooperative-cancellation hook tools call at safe points to abort execution early.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tool/CancellationToken.java:58
* @since 1.0.0
* @see DefaultCancellationToken
* @see CancellableAsyncToolCallback
*/
public interface CancellationToken {
/**
* Checks if cancellation has been requested.
* @return true if cancelled
*/
boolean isCancelled();
/**
* Throws ToolCancelledException if cancelled.
* @throws ToolCancelledException if cancellation was requested
*/
default void throwIfCancelled() throws ToolCancelledException {
if (isCancelled()) {
throw new ToolCancelledException("Tool execution was cancelled");
}
}
/**
* Registers a callback to be invoked when cancellation is requested.
*
* <p>If cancellation has already been requested, the callback may be invoked
* immediately (implementation-dependent).</p>
*
* @param callback the callback to run on cancellation
*/
void onCancel(Runnable callback);
/**
* A no-op cancellation token that is never cancelled.
*
* <p>This instance is used as a default when cancellation support is not needed.
* Since this token can never be cancelled, {@link #onCancel(Runnable)} is a no-opView on GitHub (pinned to f82da0b50f)
Solutions
- Catch ToolCancelledException in the tool and return/partial result gracefully instead of letting it bubble as an error.
- Verify no code path cancels the token prematurely (e.g. scope closing too early).
- Call throwIfCancelled() at regular checkpoints in long-running tools for fast aborts.
- Clean up resources in a finally block so cancellation leaves no leaked state.
Example fix
// before
for (Item i : items) { process(i); }
// after
for (Item i : items) {
token.throwIfCancelled();
process(i);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (token.isCancelled()) { /* skip work before starting */ } Try / catch
try { token.throwIfCancelled(); doWork(); } catch (ToolCancelledException e) { cleanup(); return partialResult; } Prevention
- Insert throwIfCancelled checkpoints in loops
- Use finally blocks for resource cleanup
- Do not cache 'not cancelled' decisions across long steps
- Only cancel tokens deliberately
When it happens
Trigger: A tool calls token.throwIfCancelled() after CancellationToken.cancel() was invoked from another thread (timeout, user abort, upstream interruption).
Common situations: Long-running tools that poll the token between steps; agents cancelling in-flight tool calls when the user interrupts; watchdog timeouts cancelling tools.
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
- Tool execution was cancelled
- TOOL_PARAMS_MISSING
- TOOL_EXECUTION_ERROR
- BUILD_TOOL_RESULT_ERROR
- WORKFLOW_RUN_CANCEL
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/582c1738d4dce760.
Report an issue: GitHub.