Skip to content

fix(browser): move a finished download off the CDP listener - #961

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

omartelo merged 1 commit into
mainfrom
fix/browser-downloads-move-off-listener

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Follow-up to #960, closing the two limits it left.

Why

  • A completed download was moved under the downloads lock, inside Chrome's browser event listener. Across filesystems the move is a copy as long as the file, so every browser event, and every other download's begin, waited behind it.
  • A move that failed reported the staged path, which is deleted with the profile when the browser closes.

What changed

  • progress no longer moves: a completed download keeps its name reserved. place moves it outside the lock, on its own goroutine from the listener, then frees the name. Since the session only hears completed from place, the agent's click still waits for the file to be in place, and the window's toast still names a file that exists.
  • A failed move is reported as a new state, api.DownloadFailed ("failed", lich's own, not Chrome's), with the path it would have taken; the CLI page text says download failed: <path>. The window emits no toast for it, as for a canceled one.
  • docs/ceilings.md and docs/browser-tab.md updated.

Tests

  • New: TestDownloadsKeepTheNameAndTheLockFreeWhileTheFileMoves begins another download from inside the move. It fails if the lock is held during the move (checked by moving the lock back), and the new download gets a (1).txt because the name is still reserved. New: TestDownloadLineSaysAFailedMove.
  • Changed, because the contract changed (progress no longer moves the file and returns no error; place does the move): the existing cases go through a complete helper that calls both, as the listener does. TestDownloadsReportTheWrittenFileWhenTheRenameFails became TestDownloadsReportFailedWhenTheMoveFails: a failed move now reports failed with the reserved path, not the staged path, and frees the name.
  • -race -count=50 on the download unit tests is green. The downloads live tests ran -count=20 on Linux, 20/20. The full go test ./..., go vet and the linux, darwin and windows cross-compile loop are clean.

A completed download was moved into Downloads under the downloads lock,
inside Chrome's browser event listener. Across filesystems the move is a
copy as long as the file, so every browser event, and every other
download, waited behind it.

progress now only keeps the name reserved; place moves the file outside
the lock, on its own goroutine, and the agent hears completed once the
file is in place. A move that fails is reported as a new failed state
("download failed: <path>") instead of the staged path, which goes with
the profile.
@omartelo
omartelo merged commit adecbe2 into main Oct 28, 2026
7 checks passed
@omartelo
omartelo deleted the fix/browser-downloads-move-off-listener branch October 28, 2026 13:20
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