From 9b987eefb0a2865a9fd379ff1ac2e54b6fb9156f Mon Sep 17 00:00:00 2001 From: Wali Reheman Date: Fri, 1 May 2026 13:51:21 -0700 Subject: [PATCH] fix: close previous SessionDB before replacing on cached agent SessionDB WAL handles leak when streaming.py creates a new SessionDB instance per request and replaces the cached agent's _session_db without closing the old one. Each orphaned connection holds 2 FDs (.db + .db-wal), causing FD exhaustion and EMFILE crashes after ~73 messages. Fix: close the previous _session_db before replacing it on cached agents, mirroring the close-before-replace pattern used elsewhere in the codebase. --- api/streaming.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/streaming.py b/api/streaming.py index 428292c0..03d8f63a 100644 --- a/api/streaming.py +++ b/api/streaming.py @@ -1883,6 +1883,15 @@ def _run_agent_streaming( if hasattr(agent, 'clarify_callback'): agent.clarify_callback = _agent_kwargs.get('clarify_callback') if _session_db is not None: + # Close any previously held SessionDB connection before + # replacing it. Without this, each streaming request creates + # a new SessionDB whose WAL handles leak indefinitely, + # eventually causing EMFILE crashes (#streaming FD leak). + if hasattr(agent, '_session_db') and agent._session_db is not None: + try: + agent._session_db.close() + except Exception: + pass agent._session_db = _session_db if hasattr(agent, '_api_call_count'): agent._api_call_count = 0