[Bug]: Leaving a thread detaches its browser preview and can leave automation unusable
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find an exact duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/desktop
Summary
👋 hey, i'm the human verifying the agent slop below. it's a real problem i keep running into. 😅
When I navigate away from a thread that has an active embedded browser preview, T3 Code appears to detach the preview's control session and listeners.
After returning to the thread, the old preview tab may still exist, but browser automation becomes unreliable or completely unusable. preview_snapshot can fail with UnknownVizError or remain stalled for several minutes. Reusing or reopening the affected tab does not reliably recover it; creating a fresh preview tab does.
This appears related to #3713, #3717, and #3718, but those issues do not identify switching away from a thread as the trigger.
Steps to reproduce
- Open a Codex-backed thread in T3 Code Desktop.
- Open an embedded browser preview in that thread.
- Confirm that preview automation works, for example with
preview_status,preview_snapshot, orpreview_evaluate. - Leave the thread by selecting another thread in the T3 Code sidebar.
- Return to the original thread.
- Attempt to inspect or interact with the existing preview tab.
- Retry
preview_snapshotor another automation operation if the first call fails.
Expected behavior
Leaving and returning to a thread should not invalidate its browser preview.
If T3 Code intentionally suspends or detaches previews belonging to hidden threads, returning to the thread should reattach the preview and restore automation automatically.
At minimum, the tool should return a clear, recoverable error explaining that the tab must be reattached or recreated.
Actual behavior
After the thread loses focus:
- T3 Code logs successful
PreviewManager.detachControlSessionand listener-detachment operations. - Later
preview_snapshotcalls against the affected thread's tab fail withUnknownVizError. - Some failed snapshot operations remain pending for approximately 76–320 seconds.
- Subsequent automation against the same tab may remain unusable.
- Reopening or reusing the existing tab does not reliably recover it.
- Creating a fresh preview tab restores automation.
The browser backend itself remains available: preview_status still reports automation capability, and new tabs can be created successfully. The failure therefore appears scoped to the detached thread-bound tab rather than to the global browser backend.
Impact
Major degradation or frequent failure.
Long-running agent work can lose access to its browser merely because the user visits another thread. The agent may then spend several minutes retrying a poisoned tab or incorrectly conclude that the in-app browser is globally unavailable.
This especially affects workflows where an agent continues running in the background while the user checks other threads.
Version or commit
T3 Code Nightly:
0.0.34-nightly.20260812.1072
Environment
- T3 Code Desktop
- macOS
- Codex provider
- Embedded collaborative browser/preview tools
Logs or stack traces
Representative failure:
PreviewOperationError: Desktop preview operation failed:
automationSnapshot.capturePage
[cause]: Error: UnknownVizError
One representative snapshot operation remained pending for approximately 320 seconds before failing:
PreviewManager.captureAutomationSnapshot
durationMs: 320528.876875
[cause]: Error: UnknownVizError
Sanitized trace attachment (NDJSON)
The excerpt below was derived from the local desktop trace. It contains no page content and has been sanitized by removing absolute timestamps, usernames, filesystem paths, URLs, and all thread, project, session, trace, span, and tab identifiers.
SHA-256 of the sanitized NDJSON: 09c63b5853281ad30be7639ef7a4279bdd47ba0231c6ed8db21850e813afe7d6
{"recordType":"metadata","schema":"t3code-sanitized-preview-trace-v1","platform":"macOS","appVersion":"0.0.34-nightly.20260812.1072","sanitization":["absolute timestamps replaced by relative offsets","thread, project, session, trace, tab, and span identifiers removed","usernames and filesystem paths removed","URLs and page content removed","stack frames removed"]}
{"recordType":"event","offsetMs":0,"durationMs":11.835042,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
{"recordType":"event","offsetMs":637600.796,"durationMs":114534.930542,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
{"recordType":"event","offsetMs":966494.677,"durationMs":76050.029792,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
{"recordType":"event","offsetMs":1203748.589,"durationMs":320528.876875,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
{"recordType":"event","offsetMs":1226431.167,"durationMs":1.884792,"component":"PreviewManager","operation":"detachControlSession","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226433.093,"durationMs":0.168417,"component":"PreviewManager","operation":"detachListeners","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226434.49,"durationMs":113.926,"component":"PreviewManager","operation":"detachControlSession","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226434.535,"durationMs":0.072708,"component":"PreviewManager","operation":"detachListeners","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226435.258,"durationMs":173.96875,"component":"PreviewManager","operation":"detachControlSession","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226435.273,"durationMs":0.202583,"component":"PreviewManager","operation":"detachListeners","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226437.351,"durationMs":212.145625,"component":"PreviewManager","operation":"detachControlSession","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226437.385,"durationMs":0.053125,"component":"PreviewManager","operation":"detachListeners","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226437.727,"durationMs":217.207833,"component":"PreviewManager","operation":"detachControlSession","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":1226437.733,"durationMs":0.11675,"component":"PreviewManager","operation":"detachListeners","result":"Success","target":"preview_lifecycle","error":null}
{"recordType":"event","offsetMs":2140260.862,"durationMs":8.101542,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
{"recordType":"event","offsetMs":3732905.054,"durationMs":10.752375,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
{"recordType":"event","offsetMs":3750119.288,"durationMs":15.184084,"component":"PreviewManager","operation":"captureAutomationSnapshot","result":"Failure","target":"thread_preview_tab_A","error":"UnknownVizError"}
Full unsanitized local logs are not attached because they may contain private workspace information.
Workaround
After returning to the thread:
- Stop retrying the affected tab after an
UnknownVizErroror snapshot timeout. - Create a fresh preview tab instead of reusing the old one.
- Keep the thread visible while performing snapshot- or click-dependent browser work.
Related issues
- #3713 —
preview_snapshotcan fail or time out on loaded pages and leave tab automation unusable - #3717 —
preview_clickreturns success in hidden tabs but does not dispatch the click - #3718 —
preview_open(show: true)can load a tab without showing it to the user - #5540 — Embedded browser tabs are not restored after quitting or crashing the app
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/desktop by tracing the PreviewManager detachControlSession and detachListeners calls triggered when switching threads, then reproduce the failure with preview_status or preview_snapshot. Compare the preview lifecycle before leaving and after returning to the thread. Done means returning to a thread preserves automation, reattaches it automatically, or produces a clear recoverable error instead of UnknownVizError or prolonged pending operations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100