You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug: SMTP email sends block the backend's event loop (no timeout) #3637
send_email in src/backend/services/email_service.py is async, but its SMTP branch calls the synchronous _send_smtp, which opens smtplib.SMTP(SMTP_HOST, SMTP_PORT) with no timeout. The whole send therefore runs on the backend worker's event loop. While it connects, authenticates and sends, every other request on that worker waits. A slow or unreachable SMTP server stalls the worker until the OS gives up on the socket. Login codes, invites and notifications all take this path when the email provider is smtp.
Context
Found in the review of #3634 (abilityai/trinity-enterprise#837 PR 2). Its new account endpoint bounds the invite email with asyncio.wait_for(..., 10).
That bound works for the HTTP providers (Resend, SendGrid), whose sends are real awaits.
It cannot fire for SMTP: a blocking call inside a coroutine never yields to the loop.
Installs on the console, resend or sendgrid provider are unaffected.
Acceptance Criteria
The SMTP send runs off the event loop (asyncio.to_thread), so the worker keeps serving other requests while it runs.
smtplib.SMTP(...) gets an explicit socket timeout, as a documented setting or constant.
A test blocks the way SMTP does (a thread-blocking fake, not asyncio.sleep). It shows the loop stays responsive and that a caller's asyncio.wait_for bound fires.
Callers that use the send's return value (login codes) still get it.
Activity
obasilakis commentedon Oct 19, 2026
/claim
github-actions commentedon Oct 19, 2026
@obasilakis This issue is already assigned to obasilakis. Use
/unclaimfirst if you want to take over.fix(email): run SMTP sends off the event loop with a socket timeout (#…