Skip to content

fix(browser): stage Chrome's downloads in the session profile - #960

Merged
omartelo merged 1 commit into
mainfrom
fix/browser-downloads-staging
Oct 28, 2026
Merged

omartelo merged 1 commit into
mainfrom
fix/browser-downloads-staging

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Why

TestChromeDownloadsLandInDownloadsAndThePageStays still failed on macos-latest after #959 (run 40686685056 on #955): Downloads held four GUID-named files beside the six downloads. Browser.setDownloadBehavior is browser-wide, so whatever Chrome downloads on its own, with no page and no downloadWillBegin, lands in the download path under its GUID and is never renamed. #959 switched off the optimization guide's model downloads; another background download still lands.

What changed

  • Chrome's download path is now lich-downloads inside the session's own profile dir (ephemeral, removed on close), never the user's Downloads.
  • On completion lich moves only a GUID a page announced (begin) into Downloads under its reserved name. Anything else stays in staging and goes with the profile.
  • Staging (temp dir) and Downloads may be on different filesystems or volumes: on EXDEV / ERROR_NOT_SAME_DEVICE the move copies to a hidden .<guid>.part beside the target, keeps the mode, renames it into place, then removes the staged file. A half-copied file never carries the final name.
  • profilestore.copyFile and crossDevice (the build-tagged seam) are exported as CopyFile and CrossDevice and reused, not duplicated.
  • docs/ceilings.md (downloads bullet) and docs/browser-tab.md describe staging, the cross-disk copy and that background files take the profile's disk until close. The CHANGELOG entry stays true, so it is unchanged.

The #959 disabled features stay; no new ones were added. The exact feature behind the remaining GUID files was not identified.

Tests

  • New: cross-filesystem fallback (the rename seam answers the OS's cross-device error), a GUID no page announced is not moved and Downloads stays empty, and the same-filesystem test also checks staging is emptied.
  • Changed, because the contract changed (Chrome now writes the GUID file into staging, not into Downloads): the existing downloads_test.go cases plant the GUID file in staging, and the failed-rename case expects the staged path. Their assertions on names, (1) collisions and overwrites are unchanged.
  • The live tests are unchanged.
  • go test -count=20 -run 'TestChromeDownloads|TestChromeOpenAndNavigateToAFile' ./internal/browser/ on Linux: 20/20 before, 20/20 after (the failure only showed on macOS and Windows runners).
  • gofmt, go vet ./..., go test ./... green; cross-compile loop for linux, darwin and windows clean.

Browser.setDownloadBehavior is browser-wide, so files Chrome downloads on
its own, with no page and no download event, landed in the user's
Downloads under a GUID and were never renamed (macOS and Windows runners,
after #959 switched the optimization guide's model downloads off).

Chrome now writes into a staging folder inside the session's ephemeral
profile. Only a download a page announced moves to Downloads, under its
reserved name; anything else stays in staging and is deleted with the
profile. Across filesystems or volumes the move falls back to a copy
under a hidden .part name, renamed once whole, reusing profilestore's
copy helper and cross-device seam, now exported.
@omartelo
omartelo merged commit 6fb60d8 into main Oct 28, 2026
7 checks passed
@omartelo
omartelo deleted the fix/browser-downloads-staging branch October 28, 2026 13:04
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.

1 participant