Bug: Attachment downloads fire FileDownloadedEvent twice on the first tab · Issue #6028 · browser-use/browser-use · GitHub
Skip to content

Bug: Attachment downloads fire FileDownloadedEvent twice on the first tab #6028

Description

@TanishGudise

Browser Use Version

0.13.11 (main at c75e847)

Bug Description, Steps to Reproduce, Screenshots

Clicking a link to an attachment (Content-Disposition: attachment) produces two FileDownloadedEvents for one file in the first tab DownloadsWatchdog attaches to, and one in every other tab:

Download First tab Other tabs
zip attachment 2 (auto_download=False and True) 1
PDF attachment 2 1
inline PDF (no attachment) 1 1

These are counts from real downloads in headless Chrome. The repro below gives the same result 3 runs out of 3.

Why: both download paths report the same file. Chrome's own download goes through Browser.downloadWillBegin/downloadProgress (auto_download=False). The network path, Network.responseReceived → download_file_from_url, also treats the attachment as downloadable (auto_download=True). Nothing links the two. The network path only dedupes by URL, against itself.

Why only the first tab: attach_to_target returns early once the browser-level download listener exists, before _setup_network_monitoring. So only the first tab ever gets network monitoring. That early return is also why per-tab network monitoring can't simply be turned on yet: every tab would start firing twice. It came up in review on #6022, which leaves the early return alone for this reason. Open PR #6027 makes exactly that change.

Not a duplicate of #5657 or #5519: those fix a different double dispatch, between Chrome's completion event and the filesystem poller, plus partial .crdownload files. Here the second event comes from the network-detection path. #2842 reported the same symptom on 0.7.0 and was closed as fixed in 2025-09. In this case the second event carries auto_download=True, so it comes from the network path.

Happy to open a PR making one path the source of truth if that's wanted.

Failing Python Code

# tests/ci/browser/test_attachment_download_events.py  (uses the repo's tests/ci conftest)
import asyncio

import pytest
from pytest_httpserver import HTTPServer

from browser_use.browser import BrowserProfile, BrowserSession
from browser_use.browser.events import FileDownloadedEvent, NavigateToUrlEvent


@pytest.fixture
async def session(tmp_path):
	s = BrowserSession(
		browser_profile=BrowserProfile(headless=True, user_data_dir=None, keep_alive=True, downloads_path=str(tmp_path))
	)
	await s.start()
	yield s
	await s.kill()


@pytest.mark.parametrize('tab', ['first', 'second'])
async def test_one_event_per_attachment(session: BrowserSession, httpserver: HTTPServer, tab: str):
	httpserver.expect_request('/f.zip').respond_with_data(
		b'PK\x03\x04' + b'\0' * 100,
		content_type='application/zip',
		headers={'Content-Disposition': 'attachment; filename="f.zip"'},
	)
	httpserver.expect_request('/page').respond_with_data('<a id="dl" href="/f.zip">f.zip</a>', content_type='text/html')
	await session.event_bus.dispatch(NavigateToUrlEvent(url=httpserver.url_for('/page')))
	if tab == 'second':
		await session.event_bus.dispatch(NavigateToUrlEvent(url=httpserver.url_for('/page'), new_tab=True))
	events: list[FileDownloadedEvent] = []
	session.event_bus.on(FileDownloadedEvent, lambda event: events.append(event))
	cdp = await session.get_or_create_cdp_session()
	await cdp.cdp_client.send.Runtime.evaluate(
		params={'expression': "document.getElementById('dl').click()"}, session_id=cdp.session_id
	)
	await asyncio.sleep(4)
	print(f'\n{tab} tab: {[(e.file_name, e.auto_download) for e in events]}')
	assert len(events) == 1

first fails with 2 events, second passes with 1.

LLM Model

N/A (no agent; BrowserSession only)

Operating System & Browser Versions

macOS 26.6.2, Google Chrome 154.0.8037.98 (headless)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions