alibaba/spring-ai-alibaba · error · RuntimeException
${response.getResult()}
Error message
${response.getResult()} What it means
In ToolRetryInterceptor.interceptToolCall(), if the tool handler returns a ToolCallResponse whose status is not SUCCESS, the interceptor treats it as a failure and throws RuntimeException whose message is the response result text (or "unknown error" when the result is null). This makes non-success statuses retryable like exceptions.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/toolretry/ToolRetryInterceptor.java:94
String toolName = request.getToolName();
// Check if this tool should be retried
if (toolNames != null && !toolNames.contains(toolName)) {
return handler.call(request);
}
Exception lastException = null;
// maxAttempts counts the initial call plus retries and is always >= 1, so the tool is executed at least once and is never skipped.
for (int attempt = 0; attempt < maxAttempts; attempt++) {
try {
ToolCallResponse response = handler.call(request);
if (ToolCallResponse.SUCCESS_STATUS.equals(response.getStatus())) {
return response;
}
// A non-success status is treated as a failure so it can be retried.
String result = response.getResult() != null ? response.getResult() : "unknown error";
throw new RuntimeException(result);
}
catch (Exception e) {
lastException = e;
// Check if we should retry this exception
if (!retryOn.test(e)) {
log.debug("Exception {} not configured for retry, re-throwing", e.getClass().getSimpleName());
throw e;
}
// Last attempt failed: Stop the operation
if (attempt >= maxAttempts - 1) {
break;
}
// Calculate delay
long delay = calculateDelay(attempt);
log.warn("Tool '{}' failed (attempt {}/{}), retrying in {}ms: {}",View on GitHub (pinned to f82da0b50f)
Solutions
- Fix the tool implementation to return SUCCESS status when the call actually succeeded
- Inspect the response.getResult() text in the exception message to identify the underlying tool error
- If the failure is permanent, mark the exception non-retryable via the retryOn predicate so it is rethrown immediately
Example fix
// before
return new ToolCallResponse("error: bad input", "failed");
// after
throw new IllegalArgumentException("bad input"); // or return success-status response Defensive patterns
Strategy: try-catch
Validate before calling
ToolCallResponse resp = handler.call(req);
if (!ToolCallResponse.SUCCESS_STATUS.equals(resp.getStatus())) { log.error("Tool failed: {}", resp.getResult()); }
// configure retryOn to exclude deterministic failures
ToolRetryInterceptor.builder().retryOn(e -> !(e instanceof IllegalArgumentException)).build(); Type guard
boolean isSuccess(ToolCallResponse r) { return r != null && ToolCallResponse.SUCCESS_STATUS.equals(r.getStatus()); } Try / catch
try { return interceptor.interceptToolCall(request, handler); } catch (RuntimeException e) { if (isRetryExhaustion(e)) return ToolCallResponse.of("tool unavailable: " + e.getMessage()); throw e; } Prevention
- Return SUCCESS status only when the tool truly succeeded
- Throw typed exceptions instead of error-status responses for permanent failures
- Restrict retryOn to transient exception types
- Log resp.getResult() on non-success to diagnose
When it happens
Trigger: A tool handler returns a non-SUCCESS status response, e.g. business error text returned as a result with an error status, or a result of null with a non-success status.
Common situations: Tool implementations returning error-prefixed responses instead of throwing; upstream tool API returning an error payload that the handler maps to a non-success status; null result from a failed tool.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Tool call failed after ${maxAttempts} attempts
- Tool '{}' failed (attempt {}/{}), retrying in {}ms: {}
- failed to create index
- Retry interrupted
- Model call failed (non-retryable exception)
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/226a9d121413bd50.
Report an issue: GitHub.