Skip to content

fix(browser): kill orphaned Chrome processes on Windows cleanup - #59754

Closed
Younest-git wants to merge 2 commits into
NousResearch:mainfrom
Younest-git:fix/windows-chrome-cleanup
Closed

fix(browser): kill orphaned Chrome processes on Windows cleanup#59754
Younest-git wants to merge 2 commits into
NousResearch:mainfrom
Younest-git:fix/windows-chrome-cleanup

Conversation

@Younest-git

Copy link
Copy Markdown

Summary

On Windows, browser_navigate() starts a headless Chromium via agent-browser. When the browser session is cleaned up (via inactivity timeout, explicit cleanup_browser(), or Hermes shutdown), the agent-browser daemon is killed — but its child Chrome processes remain running because Windows does not automatically terminate child processes when the parent is killed.

Over multiple calls (and across sessions), these orphaned chrome.exe processes accumulate: users report 60–150+ chrome.exe zombies consuming GBs of RAM until they manually run taskkill /f /im chrome.exe.

Changes

1. _cleanup_single_browser_session() — Windows-specific Chrome kill

After killing the agent-browser daemon and cleaning up the socket directory, run taskkill /f /im chrome.exe on Windows to terminate any leftover Chrome child processes. The call is wrapped in a try/except so it never blocks cleanup:

if sys.platform == "win32":
    try:
        subprocess.run(["taskkill", "/F", "/IM", "chrome.exe"],
                       capture_output=True, timeout=5)
    except Exception:
        pass

2. Lower DEFAULT_SESSION_INACTIVITY_TIMEOUT from 120s → 30s

The inactivity-based cleanup thread runs every 30s. With a 120s timeout, orphaned sessions can survive for up to 2 minutes. Reducing to 30s tightens the window significantly without risking premature reaping during normal use.

Testing

  • On Windows: verified that browser_navigate() + inactivity timeout triggers cleanup, and that taskkill removes all chrome.exe processes
  • On non-Windows: the sys.platform == "win32" guard ensures no behavioral change
  • The subprocess.run() call has a 5-second timeout and is wrapped in try/except — a hung taskkill cannot block cleanup

Related

Fixes the long-standing issue documented in the cleanup-chromium-leftovers community skill, where users had to rely on external scripts or manual taskkill to reclaim RAM.

On Windows, killing the agent-browser daemon process does NOT
automatically terminate its child Chrome processes. These orphaned
chrome.exe processes accumulate over multiple browser_navigate calls,
consuming GBs of RAM.

Two changes:

1. In _cleanup_single_browser_session(): after killing the daemon
   and cleaning up the socket directory, run taskkill /f /im chrome.exe
   to ensure any leftover Chrome child processes are terminated.
   This is Windows-only (sys.platform == 'win32').

2. Lower DEFAULT_SESSION_INACTIVITY_TIMEOUT from 120s to 30s so
   the inactivity-based cleanup reaps sessions faster, reducing the
   window in which orphans can accumulate.
@alt-glitch alt-glitch added type/bug Something isn't working tool/browser Browser automation (CDP, Playwright) platform/windows Native Windows-specific behavior or breakage P2 Medium — degraded but workaround exists sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Jul 6, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: competes with #43577 for the same Windows orphaned-Chrome cleanup goal. This PR runs a blanket taskkill /F /IM chrome.exe (kills every chrome.exe, including the user's own browser) plus lowers the default inactivity timeout 120s->30s; #43577 takes a more surgical approach (_reap_orphaned_chrome_processes via wmic, only reaping Chrome reparented to Explorer.exe, skipped while sessions are active). Both target the #32047 orphan leak. Flagging the cluster so a maintainer can pick the safer approach.

The _build_browser_env() function strips credentials from the
subprocess environment and only re-adds keys in _BROWSER_PASSTHROUGH_KEYS.
AGENT_BROWSER_EXECUTABLE_PATH and AGENT_BROWSER_ARGS were missing from
this allowlist, so user-configured env vars from .env never reached the
agent-browser CLI.

Add both keys so that:
- AGENT_BROWSER_EXECUTABLE_PATH actually points Playwright's Chromium
- AGENT_BROWSER_ARGS (e.g. --no-sandbox) are passed to the Chrome binary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows tool/browser Browser automation (CDP, Playwright) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants