{"repo":"NousResearch/hermes-agent","public_id":"2136","display_label":"Fix resource leak and double socket close in tools","summary":"These entries all address the same issue: a resource leak and double socket close bug in the code execution tool. The members appear to be duplicates or near-duplicates of the same fix.","subsystem":"agent","counts":{"members":5,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":3},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":2381},"resolution":{"state":"resolved","by":"pr-2381"},"freshness":{"state":"stale","last_verified_at":"2026-03-21T22:55:25+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.4},"fix_edges":[{"issue_number":2136,"pr_number":2381,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":2136,"title":"fix(tools): resource leak and double socket close in code_execution_tool","url":null,"state":"closed"},{"kind":"pr","number":2140,"title":"fix(tools): resource leak and double socket close in code_execution_tool","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#2381","number":2381},{"kind":"pr","value":"#2250","number":2250}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":2250,"title":"fix(tools): fix resource leak and double socket close in code_execution_tool","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#2381","number":2381}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":2291,"title":"fix(tools): resource leak and double socket close in code_execution_tool","url":null,"state":"closed","close_reason":{"category":"implemented_elsewhere","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":2381,"title":"fix(tools): resource leak and double socket close in code_execution_tool","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["tools/code_execution_tool.py"],"fix_hunks":[{"file":"tools/code_execution_tool.py","hunks":["@@ -300,16 +300,16 @@ def _rpc_server_loop(\n                 # their status prints don't leak into the CLI spinner.\n                 try:\n                     _real_stdout, _real_stderr = sys.stdout, sys.stderr\n-                    sys.stdout = open(os.devnull, \"w\")\n-                    sys.stderr = open(os.devnull, \"w\")\n+                    devnull = open(os.devnull, \"w\")\n                     try:\n+                        sys.stdout = devnull\n+                        sys.stderr = devnull\n                         result = handle_function_call(\n                             tool_name, tool_args, task_id=task_id\n                         )\n                     finally:\n-                        sys.stdout.close()\n-                        sys.stderr.close()\n                         sys.stdout, sys.stderr = _real_stdout, _real_stderr\n+                        devnull.close()\n                 except Exception as exc:\n                     logger.error(\"Tool call failed in sandbox: %s\", exc, exc_info=True)\n                     result = json.dumps({\"error\": str(exc)})","@@ -574,6 +574,7 @@ def _drain_head_tail(pipe, head_chunks, tail_chunks, head_bytes, tail_bytes, tot\n \n         # Wait for RPC thread to finish\n         server_sock.close()  # break accept() so thread exits promptly\n+        server_sock = None  # prevent double close in finally\n         rpc_thread.join(timeout=3)\n \n         # Build response\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}