fix: cap send retries to prevent infinite loop on persistent SMTP failures
linuztx committed
Mar 16, 2026 at 09:13 UTC
8596eaf6fec251ecfd3790c9ae38028784bb2cf6
2 files changed
+28
-5
plugins/_email_integration/extensions/python/process_chain_end/_55_email_reply.py
+26
-4
@@ -6,6 +6,9 @@ from helpers.print_style import PrintStyle
6
from agent import AgentContext, LoopData, UserMessage
7
from plugins._email_integration.helpers.dispatcher import CTX_EMAIL_HANDLER, CTX_EMAIL_ATTACHMENTS
8
9
+MAX_SEND_RETRIES: int = 2
10
+CTX_SEND_FAILURES: str = "_email_send_failures"
11
+
12
13
class EmailAutoReply(Extension):
14
@@ -31,8 +34,22 @@ class EmailAutoReply(Extension):
34
):
35
from plugins._email_integration.helpers.handler import send_email_reply
36
error = await send_email_reply(context, response_text, attachments)
34
- if error:
35
- _notify_agent_of_failure(context, error)
37
+ if not error:
38
+ context.data[CTX_SEND_FAILURES] = 0
39
+ return
40
+ failures = context.data.get(CTX_SEND_FAILURES, 0) + 1
41
+ context.data[CTX_SEND_FAILURES] = failures
42
+ if failures <= MAX_SEND_RETRIES:
43
+ _notify_agent_of_failure(context, error, failures)
44
+ else:
45
+ PrintStyle.error(
46
+ f"Email send failed {failures} times, giving up: {error}"
47
+ )
48
+ context.log.log(
49
+ type="error",
50
+ heading="Email send failed (max retries reached)",
51
+ content=error,
52
+ )
53
54
55
# ------------------------------------------------------------------
@@ -50,8 +67,13 @@ def _extract_last_response(context: AgentContext) -> str:
67
return ""
68
69
53
-def _notify_agent_of_failure(context: AgentContext, error: str):
70
+def _notify_agent_of_failure(
71
+ context: AgentContext, error: str, attempt: int,
72
+):
73
from plugins._email_integration.helpers.handler import _read_fw
55
- msg = _read_fw("fw.email.send_failed.md", error=error)
74
+ msg = _read_fw(
75
+ "fw.email.send_failed.md", error=error, attempt=str(attempt),
76
+ max_retries=str(MAX_SEND_RETRIES),
77
+ )
78
context.log.log(type="error", heading="Email send failed", content=error)
79
context.communicate(UserMessage(message="", system_message=[msg]))
plugins/_email_integration/prompts/fw.email.send_failed.md
+2
-1
@@ -1,3 +1,4 @@
1
-email send failed: {{error}}
1
+email send failed (attempt {{attempt}}/{{max_retries}}): {{error}}
2
previous response was NOT delivered to user
3
retry without problematic content or inform user via alternative means
4
+if attachment caused the issue, retry without it