{"record":{"id":"1def4f7fb2463208","repo":"alibaba/spring-ai-alibaba","slug":"retry-interrupted-1def4f","errorCode":null,"errorMessage":"Retry interrupted","messagePattern":"Retry interrupted","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/toolretry/ToolRetryInterceptor.java","lineNumber":120,"sourceCode":"\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Last attempt failed: Stop the operation\n\t\t\t\tif (attempt >= maxAttempts - 1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Calculate delay\n\t\t\t\tlong delay = calculateDelay(attempt);\n\t\t\t\tlog.warn(\"Tool '{}' failed (attempt {}/{}), retrying in {}ms: {}\",\n\t\t\t\t\t\ttoolName, attempt + 1, maxAttempts, delay, e.getMessage());\n\n\t\t\t\ttry {\n\t\t\t\t\tThread.sleep(delay);\n\t\t\t\t}\n\t\t\t\tcatch (InterruptedException ie) {\n\t\t\t\t\tThread.currentThread().interrupt();\n\t\t\t\t\tthrow new RuntimeException(\"Retry interrupted\", ie);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// All retries exhausted\n\t\tif (onFailure == OnFailureBehavior.RAISE) {\n\t\t\tthrow new RuntimeException(\"Tool call failed after \" + maxAttempts + \" attempts\", lastException);\n\t\t}\n\t\telse {\n\t\t\t// Return error message as tool response\n\t\t\tString errorMessage = errorFormatter != null\n\t\t\t\t\t? errorFormatter.apply(lastException)\n\t\t\t\t\t: \"Tool call failed after \" + maxAttempts + \" attempts: \" + lastException.getMessage();\n\n\t\t\tlog.error(\"Tool '{}' failed after {} attempts: {}\", toolName, maxAttempts, lastException.getMessage());\n\t\t\treturn ToolCallResponse.of(request.getToolCallId(), request.getToolName(), errorMessage);\n\t\t}\n\t}","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/toolretry/ToolRetryInterceptor.java#L102-L138","documentation":"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.","triggerScenarios":"The thread executing interceptToolCall is interrupted (Thread.interrupt()) while sleeping between retries, typically during shutdown or task cancellation.","commonSituations":"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.","solutions":["Avoid interrupting the thread running the agent, or let shutdown complete the in-flight tool call","Handle the RuntimeException and its InterruptedException cause gracefully at shutdown boundaries","Use an executor lifecycle that waits for tasks instead of shutdownNow()","Reduce delay/maxAttempts so retries finish before shutdown"],"exampleFix":"// before\nexecutor.shutdownNow(); // interrupts in-flight retries\n// after\nexecutor.shutdown();\nexecutor.awaitTermination(30, TimeUnit.SECONDS);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return interceptor.interceptToolCall(request, handler); } catch (RuntimeException e) { if (e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); return ToolCallResponse.of(\"retry cancelled\"); } throw e; }","preventionTips":["Use graceful shutdown (shutdown + awaitTermination) instead of shutdownNow","Keep retry budgets small so calls finish before shutdown","Preserve the interrupt flag after catching","Run agent work on threads not subject to aggressive timeout interrupts"],"tags":["interruption","retry","threading","cancellation"],"backgroundTag":"request-timeout","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}