What happened
Desktop's history search modal ("Search task titles and content…" / "搜索任务标题和内容…") has two related cancellation defects:
- Replacing a query or closing the modal discards stale results, but the previous search can continue reading transcripts and scanning other sessions.
- If an earlier request remains pending, reopening the modal can retain the old input and loading spinner. The spinner can also remain visible after a newer query has already returned results.
Expected: dismissing or superseding a search stops further transcript reads; reopening starts idle with an empty input, and completing the current query clears its spinner without waiting for older requests. An already dispatched transcript page may finish, but cancellation must prevent subsequent pages and sessions.
How to reproduce
- Open Desktop's history search modal from the task sidebar. Use a history with long transcripts, or a slow Owner Host, so a search remains pending.
- Enter a keyword, close the modal before the request finishes, and reopen it. Observe the stale input/loading state.
- Alternatively, start a slow query, replace it with another keyword, and let the newer request complete first. Its results appear while the spinner remains active.
- Observe transcript reads for the abandoned request: they can continue after replacement or dismissal.
For deterministic UI reproduction, mount the real SearchModal with deferred searchThread responses: leave request A unresolved, then close/reopen or resolve request B. Before the fix, both cases still expose a Loading status element. For the scanning behavior, hold the first transcript read pending and check whether cancellation closes that search's handle and prevents opening the next session.
Environment
- Source baseline:
4cd71eaed2 (original report investigated at a9f5f6790d).
- OS: macOS 15.7.3, Apple Silicon.
- Surface: Desktop history search; deterministic UI reproduction also uses the real component in Chromium.
- Node.js: v24.14.0.
Logs, screenshots, or additional context
createThreadSearchSource.cancel() currently only advances a generation counter; Desktop does not propagate cancellation to runThreadSearch. Astryx's asynchronous palette transition also remains pending until the abandoned promise settles. These are separate parts of the same request lifecycle.
A linked fix will include synthetic before/after screenshots and regression tests for dismissal, rapid query replacement, multi-Host cancellation, renderer teardown, and reconnect replay. No private conversation data is included.
Prepared and submitted with Codex on behalf of @liuxiaocs7. Codex contributed diagnosis, implementation, tests, and this report.
What happened
Desktop's history search modal ("Search task titles and content…" / "搜索任务标题和内容…") has two related cancellation defects:
Expected: dismissing or superseding a search stops further transcript reads; reopening starts idle with an empty input, and completing the current query clears its spinner without waiting for older requests. An already dispatched transcript page may finish, but cancellation must prevent subsequent pages and sessions.
How to reproduce
For deterministic UI reproduction, mount the real
SearchModalwith deferredsearchThreadresponses: leave request A unresolved, then close/reopen or resolve request B. Before the fix, both cases still expose aLoadingstatus element. For the scanning behavior, hold the first transcript read pending and check whether cancellation closes that search's handle and prevents opening the next session.Environment
4cd71eaed2(original report investigated ata9f5f6790d).Logs, screenshots, or additional context
createThreadSearchSource.cancel()currently only advances a generation counter; Desktop does not propagate cancellation torunThreadSearch. Astryx's asynchronous palette transition also remains pending until the abandoned promise settles. These are separate parts of the same request lifecycle.A linked fix will include synthetic before/after screenshots and regression tests for dismissal, rapid query replacement, multi-Host cancellation, renderer teardown, and reconnect replay. No private conversation data is included.
Prepared and submitted with Codex on behalf of @liuxiaocs7. Codex contributed diagnosis, implementation, tests, and this report.