alibaba/spring-ai-alibaba · warning · RuntimeException

Retry interrupted

Error message

Retry interrupted

What it means

ToolRetryInterceptor sleeps for the computed backoff delay between attempts. If the sleeping thread is interrupted, it restores the interrupt flag and throws RuntimeException("Retry interrupted", ie), aborting the retry loop.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/toolretry/ToolRetryInterceptor.java:120

					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: {}",
						toolName, attempt + 1, maxAttempts, delay, e.getMessage());

				try {
					Thread.sleep(delay);
				}
				catch (InterruptedException ie) {
					Thread.currentThread().interrupt();
					throw new RuntimeException("Retry interrupted", ie);
				}
			}
		}

		// All retries exhausted
		if (onFailure == OnFailureBehavior.RAISE) {
			throw new RuntimeException("Tool call failed after " + maxAttempts + " attempts", lastException);
		}
		else {
			// Return error message as tool response
			String errorMessage = errorFormatter != null
					? errorFormatter.apply(lastException)
					: "Tool call failed after " + maxAttempts + " attempts: " + lastException.getMessage();

			log.error("Tool '{}' failed after {} attempts: {}", toolName, maxAttempts, lastException.getMessage());
			return ToolCallResponse.of(request.getToolCallId(), request.getToolName(), errorMessage);
		}
	}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Avoid interrupting the thread running the agent, or let shutdown complete the in-flight tool call
  2. Handle the RuntimeException and its InterruptedException cause gracefully at shutdown boundaries
  3. Use an executor lifecycle that waits for tasks instead of shutdownNow()
  4. Reduce delay/maxAttempts so retries finish before shutdown

Example fix

// before
executor.shutdownNow(); // interrupts in-flight retries
// after
executor.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS);
Defensive patterns

Strategy: try-catch

Try / catch

try { return interceptor.interceptToolCall(request, handler); } catch (RuntimeException e) { if (e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); return ToolCallResponse.of("retry cancelled"); } throw e; }

Prevention

When it happens

Trigger: The thread executing interceptToolCall is interrupted (Thread.interrupt()) while sleeping between retries, typically during shutdown or task cancellation.

Common situations: Application shutdown or Spring context close cancelling worker threads; executor shutdownNow() on a task running an agent; timeout cancellation frameworks interrupting the tool-executing thread.

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/1def4f7fb2463208. Report an issue: GitHub.