alibaba/spring-ai-alibaba · error · WebFetchException
Retry interrupted
Error message
Retry interrupted
What it means
WebFetchTool.fetchHtmlWithRetry wraps fetch failures in a WebFetchException. When the thread waiting between/inside fetch attempts is interrupted, the InterruptedException is caught, the interrupt flag is restored via Thread.currentThread().interrupt(), and this 'Retry interrupted' exception is thrown. It signals the retry loop was aborted by cancellation/shutdown rather than a network problem.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/WebFetchTool.java:265
logger.warn("Fetch attempt {} returned server error {} for URL: {}", attempt + 1,
response.statusCode(), url);
attempt++;
continue;
}
return response;
}
catch (WebFetchException e) {
lastException = e;
if (e.getCause() instanceof InterruptedException) {
throw e;
}
logger.warn("Fetch attempt {} failed for URL: {}: {}", attempt + 1, url, e.getMessage());
attempt++;
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new WebFetchException("Retry interrupted", e);
}
}
if (lastException == null) {
throw new WebFetchException("Failed after " + (this.maxRetries + 1) + " attempts", null);
}
else if (lastException instanceof WebFetchException) {
throw new WebFetchException("Failed after " + (this.maxRetries + 1) + " attempts", lastException);
}
else {
throw new WebFetchException(
"Failed after " + (this.maxRetries + 1) + " attempts: " + lastException.getMessage(),
lastException);
}
}
private HttpResponse<String> fetchHtml(String url) {
HttpRequest request = HttpRequest.newBuilder()View on GitHub (pinned to f82da0b50f)
Solutions
- Let the interruption propagate: treat it as cancellation and stop the workflow rather than retrying or fetching again.
- Check upstream code that calls Thread.interrupt() (Future.cancel(true), executor shutdownNow, timeouts) and extend its timeout if cancellation is unintentional.
- Catch WebFetchException around the tool call and surface a clean cancellation message to the agent response.
- Preserve the interrupt status in your own handler (re-interrupt) so outer layers see cancellation.
Example fix
// before
String html = webFetchTool.fetch(url);
// after
try {
String html = webFetchTool.fetch(url);
} catch (WebFetchException e) {
if (e.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
return "fetch cancelled";
}
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try {
String html = webFetchTool.fetch(url);
} catch (WebFetchException e) {
if (e.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
return Optional.empty(); // treat as cancelled
}
throw e;
} Prevention
- Avoid interrupting worker threads mid-fetch; prefer cooperative cancellation points between nodes
- Increase deadlines in code that cancels fetches via Future.cancel(true)
- Check Thread.currentThread().isInterrupted() before starting long fetch chains
When it happens
Trigger: Thread interrupt during WebFetchTool fetchHtmlWithRetry — e.g. task cancellation, executor shutdownNow, or a timeout mechanism interrupting the calling thread while the fetch/sleep between attempts is in progress.
Common situations: Calling the tool from a thread pool whose tasks get cancelled; Spring @Async with timeouts; shutting down an application while a web-fetch agent node is running; wrapping fetch in Future.get(timeout) which interrupts the worker.
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
- Retry interrupted
- Retry interrupted
- Failed after attempts
- Failed after attempts:
- Request was interrupted
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/0dc99753de9d9263.
Report an issue: GitHub.