OpenHands / OpenHands/software-agent-sdk

[Bug]: Duplicate browser recording starts can orphan an active flush task

Open
#4,666 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

architecture bug priority:medium ready-for-dev session tools
Dominant language
Python
Stars
1.1k
Forks
539
Avg merge
1d 19h
Merged PRs (30d)
137

Description

Bug Description

CustomBrowserUseServer unconditionally replaces its addressable recording controller on every start (openhands-tools/openhands/tools/browser_use/server.py:127-145). Each RecordingSession owns its own active flag and background flush task (recording.py:136-140,375-404).

If recording is already active, the newly created controller sees the page-side recorder as already running but still starts another Python flush loop. The old controller/task becomes unreachable through server stop/cleanup. Both tasks drain the same page-global rrweb buffer, so events can be split between directories and the old task can continue indefinitely.

Expected Behavior

One browser session should have one authoritative recording controller and at most one active flush task. Duplicate starts should be idempotent and must not replace the active controller.

Actual Behavior

An independent, self-contained reproducer is posted in the issue comments. Save
it as /tmp/repro_4666.py, then run:

uv run python /tmp/repro_4666.py

On SDK commit bc5dfc50d, it exercises the real BrowserToolExecutor, headless Google Chrome, CDP, rrweb, and recording storage; no mocks and prints:

first_start=Recording started
second_start=Already recording
session_replaced=True
first_session_still_active=True
first_flush_task_pending=True
second_stop=Recording stopped. Captured 2 events in 1 file(s).
first_task_pending_after_stop=True
Suggested Implementation

Reuse one controller for the browser-session lifetime. Serialize start/stop/cleanup transitions, return the existing “Already recording” result on duplicate start, and cancel/await the sole task before discarding the controller when the browser session closes.

Acceptance Criteria
  • Two starts retain one controller and one flush task.
  • Duplicate start cannot split events across recording directories.
  • Start → stop → start creates distinct runs without leaking tasks.
  • Browser cleanup cancels/awaits the active task.
  • A new browser session reinjects recording scripts and receives a fresh controller.
  • Public tool schemas and established result strings remain unchanged.
Version

Current main at 6d3881035. Existing issue search found no duplicate.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with CustomBrowserUseServer in openhands-tools/openhands/tools/browser_use/server.py:127-145 and RecordingSession in recording.py:136-140,375-404. Run the independent reproducer with uv run python /tmp/repro_4666.py to observe duplicate starts and pending tasks. Done means one controller and flush task per browser session, clean start-stop-start behavior, and cleanup that cancels and awaits the active task.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.