Skip to content

fix(downloads): don't address the browser's implicit context by id - #628

Merged
route merged 1 commit into
mainfrom
fix/download-behavior-implicit-context
Sep 2, 2026
Merged

fix(downloads): don't address the browser's implicit context by id#628
route merged 1 commit into
mainfrom
fix/download-behavior-implicit-context

Conversation

@route

@route route commented Sep 2, 2026

Copy link
Copy Markdown
Member

Closes #546.

The bug

Downloads#set_behavior sent browserContextId: @page.context_id unconditionally. For a page in the browser's implicit context — the one Chrome puts its startup window in — that id isn't addressable, so the first page died with:

Ferrum::BrowserError: Failed to find browser context for id 97B71EC807EDF5868B937479FC2E4324
  lib/ferrum/client.rb:367 raise_browser_error
  lib/ferrum/page.rb:448   Ferrum::Page#command

It reproduces on main against any browser that came up with its own startup window (a Chrome in a sidecar container, browserless) when :save_path is set, since prepare_page configures the download behavior for every page. It is not flatten-specific — flatten: false fails identically — and not version-specific either, Chrome 152 fails the same way as the 119 in the report. Same root cause as #578/#627, which fixed it for Target.createTarget only.

The fix

Target#context_id, and with it Page#context_id, is nil for the implicit context, so a caller scoping a command to a browser context can tell it apart from the id alone, without reaching for the context object:

options = { browserContextId: @page.context_id } if @page.context_id
@page.command("Browser.setDownloadBehavior", **Hash(options), ...)

Context#create_target and Contexts#dispose keep the implicit? checks they already had, so all three CDP calls that take a browserContextId are covered. Those three are the only ones in the codebase — everything else is target- or session-scoped.

Two alternatives that don't work, both checked against a live browser:

  • Always omitting browserContextId: downloads in a context we created come back canceled, the behavior lands on the default context instead.
  • Setting the behavior once per context from the browser session: files save, but Browser.downloadWillBegin/downloadProgress are then delivered to the browser session and page.downloads.files/#wait track nothing. The command has to stay on the page's session.

Cuprite builds its own pages with Page.new(target.client, context_id: target.context_id, ...), so it picks this up unchanged.

Verification

  • New spec in spec/downloads_spec.rb, using with_external_browser(incognito: false) for a browser with a startup window. It fails with Failed to find browser context for id without the fix.
  • Full suite: 614 examples, 0 failures.
  • Manually, against a startup-window Chrome in both flatten modes: the download completes, the file is saved and stays tracked on the page, while a context created by Ferrum in the same browser still saves to its own save_path.
  • rbs validate passes. Page#context_id is String? now, since Target is what passes it and it can be nil.

Passing `:save_path` to a browser that came up with its own startup window died on the first page with
`Failed to find browser context for id`, `Browser.setDownloadBehavior` scoped the download behavior to
`browserContextId` unconditionally. That window lives in the browser's implicit context, which Chrome refuses to
address by id, the same reason `Target.createTarget` omits it there.

`Target#context_id`, and with it `Page#context_id`, is now nil for that context, so anything scoping a command to a
browser context can tell it apart by the id alone. The command must keep going through the page's session, sending
it on the browser session delivers `Browser.downloadWillBegin`/`downloadProgress` there and `page.downloads` stops
tracking the files it saves.

Closes #546
@route
route merged commit a6406b5 into main Sep 2, 2026
7 checks passed
@route
route deleted the fix/download-behavior-implicit-context branch September 2, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Browser.setDownloadBehavior fails with “Failed to find browser context …” when using flatten: true (Target.setAutoAttach)

1 participant