OpenHands / OpenHands/software-agent-sdk
[Bug]: Duplicate browser recording starts can orphan an active flush task
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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