Skip to content

browser: primary-agent tabs never cleaned up — cleanupBrowserSessionsForLifecycleEnd not wired for primary sessions #71165

@dwbutler

Description

@dwbutler

Summary

cleanupBrowserSessionsForLifecycleEnd() is only called from two places in runtime code:

  • src/agents/subagent-registry-lifecycle.ts:611 — subagent completion
  • src/gateway/server-cron.ts:305 — cron-isolated agent turn completion

Primary agents' interactive (channel/paired) sessions have no corresponding call. Tabs opened during normal agent-user chat are tracked in the session-tab registry but never closed until the agent process or browser container is restarted externally.

In practice this means a tab with a hot JS loop (setInterval, WS reconnect, animation frame, etc.) pegs CPU indefinitely.

Evidence

On a production gateway we observed a renderer process at 31.5% CPU for ~47 hours inside an openclaw-sbx-browser-agent-* container. The container sessionKey label was agent:<agent-id>, and the agent process had been running continuously since the browser was first used. Restarting the container (docker restart) reclaimed the CPU immediately; the agent reopened pages on next use without issue.

Two browser containers on the same host had been up for 24h+ / 47h+ respectively.

Expected

Primary-agent sessions should participate in some form of tab lifecycle. Options (any or a combination):

  1. Idle timeout per tab — close tabs with no navigation/interaction for N minutes (config-driven).
  2. Periodic tab GC — on a timer, close tabs older than N minutes from primary sessions (same mechanism subagents/cron already have at cleanupBrowserSessionsForLifecycleEnd, just timer-triggered).
  3. Per-session tab cap — enforce a max open-tab count per agent, closing LRU tabs when exceeded.

No strong opinion on which; (2) is probably the smallest change given the infrastructure already exists.

Actual

Zero cleanup. Tabs persist for the lifetime of the agent process (days/weeks in practice). Stuck-JS tabs silently burn CPU until something external kills them.

Workaround

Operators can add a nightly cron to docker restart openclaw-sbx-browser-agent-* containers. This works but is blunt — it also closes healthy tabs that would otherwise be reused.

Related

  • src/browser-lifecycle-cleanup.ts — the cleanup entrypoint; only the two call sites above exercise it
  • src/plugin-sdk/browser-maintenance.tssession-tab-registry.ts — the tab tracking infrastructure that already distinguishes per-session ownership

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions