[Bug]: preview_open still returns visible: false after explicit open/show request#17015

opened21d agobyNnima20002000

Related issue

Possible recurrence of #3718, which is closed. This report captures a new observation on 2026-10-08.

Area

Collaborative browser / preview MCP tools.

Steps to reproduce

In a T3 Code thread using the Codex provider, ask the agent to open T3's browser and go to Google. The following exact tool sequence was executed:

  1. preview_status({}) returned available: false, visible: false, and tabId: null.
  2. preview_open({"url":"https://www.google.com"}) returned the response below.
  3. preview_open({"tabId":"tab_1","open":true,"show":true}) returned the same response, including visible: false.

Actual behavior

Both open calls succeeded and returned:

json
1{
2 "available": true,
3 "visible": false,
4 "tabId": "tab_1",
5 "url": "https://www.google.com/",
6 "title": "Google",
7 "loading": false,
8 "viewportSetting": {"_tag":"freeform","width":1280,"height":800},
9 "viewport": {"width":1280,"height":800}
10}

The agent reported that the preview was not visible. The user then asked what visibility meant and to whom. The exposed tool descriptions describe visibility but do not specify its observer or whether it is an immediate/eventually updated panel state. Therefore the agent could not justify interpreting visible: false as proof that the user could not see the browser.

This report does not establish that the user-facing panel was actually hidden; the confirmed observation is the returned status after the explicit open/show request. A later read-only preview_status({"tabId":"tab_1"}) returned visible: true with a different page, so the initial false state was not permanent. No intervening user interactions were captured.

Expected behavior

After an explicit open: true / show: true request, return visibility matching the resulting user-facing preview state, or clearly distinguish a pending display request from confirmed visibility. Document exactly what visible measures and whose view it describes, so agents can report it accurately.

Impact

Confusing user-facing status: a successful request to open the browser leads the agent to report that it is not visible, without enough information to explain that claim.

Environment

Linux, T3 Code with Codex harness, GPT-6.1-Sol. T3 Code version/commit was not captured.

Note

Grok responding on behalf of Julius.

Thanks for the precise call sequence. I checked this against current main (d720210). In short, preview_open never waits for a client to actually show the tab, and visible only counts streamed viewers. Details below.

What's confirmed on main

  • Since #15328 (Oct 6), preview_open is served by the environment's own browser, which registers as the preferred automation host (ServerBrowser.ts L2150-L2158). With open/show set, it publishes a reveal request and then returns status right away (L1536-L1551). requestReveal only updates the session snapshot and emits an event, and nothing comes back (Manager.ts L468-L497). The app opens the panel later, when it sees that event, and only for the active thread (ChatView.tsx L5513-L5543).
  • In both preview_open and preview_status, visible is just tab.viewers.size > 0 (L1117). It means "some client has a frame stream open for this tab." The streamed surface only connects while it's shown (ServerBrowserSurface.tsx L367), so a status read immediately after the reveal request will usually say false. A later preview_status says true once the panel has connected. That matches what you saw.
  • In the desktop app talking to its own local server, server tabs render natively in a <webview> and are not streamed (previewRuntime.ts L26-L42, PreviewView.tsx L167-L170). There, no viewer is ever added, so visible stays false even while the tab is on screen, unless another client is also streaming it. The server's own pointer code already assumes "a desktop-rendered tab is always on screen" (L1366-L1368), but status doesn't take that into account. The desktop channel only reports attached/detached/cdp, with no shown/hidden signal (desktopBrowser.ts L21-L28).
  • The docs gap is real. preview_status lists "visibility" without defining it (tools.ts L65-L67), and the schema field has no description (previewAutomation.ts L77). Also, the open parameter says it "Defaults to true," but the handler deliberately leaves it unset so the user's auto-show preference decides (handlers.ts L36-L53).

Relation to #3718

#3718 was closed after #9484 merged. That fix lived in the old client-side automation host (PreviewAutomationHosts.tsx). That host also waited up to 500 ms for the surface to report visible before returning, and returned false without any error if it timed out. #15328 deleted that file, so neither the fix nor the settle wait applies to the server-hosted path.

Which path you hit (unconfirmed)

The response you pasted has no control, dialog, fileChooser or tabs fields, which main's server status always includes (L1115-L1155). Its freeform 1280×800 viewport also matches the old client host's default for agent tabs. So your build may predate #15328, in which case the likely cause is that 500 ms settle timing out. Could you share the T3 Code version, and say whether this was the desktop app or a browser? Either way, current main still shows the mismatch for the reasons above.

Possible fixes (not yet tried)

  • After a reveal request, have preview_open wait a short, bounded time for the tab to actually be shown (as the old host did) before reporting status.
  • Give desktop-rendered tabs a real visibility signal, for example a shown/hidden event on the desktop browser channel, so visible isn't tied to streaming.
  • Report "reveal requested" separately from confirmed visible, and document visible as "a T3 client is currently displaying this tab."

Workaround

Don't treat visible: false right after preview_open as proof the user can't see the tab. Re-check with preview_status after a moment. In the desktop app with a local environment, visible isn't reliable at all right now. To check whether the tab is usable for automation, look at available, url and title, not visible.

Related

  • #15328: introduced the server-hosted path.
  • #9484 / #3718: the earlier fix.
  • Open PR #16956 touches this same code and keeps the viewers.size > 0 meaning. Open PRs #16835 and #16963 also modify ServerBrowser.ts. None of them changes how visible is computed.
  • #6355, #7212 and #16901 are in the same area, with different symptoms.
Synced from GitHub

Another data point, on a newer nightly and on the Windows desktop + WSL server-runtime path (streamed tabs, not the local <webview> case).

Environment (2026-10-21)

ComponentValue
Windows clientWindows 11 10.0.26300.9711, T3 Code (Nightly)
WSL T3 server0.1.1-nightly.20261019.3360, Linux x64
WSL OS/kernelUbuntu 24.04.4 LTS, 6.18.33.2-microsoft-standard-WSL2
Browser runtime / profileserver / default, Chrome Headless Shell 154.0.8037.92
Agent providerClaude Agent (Claude Code harness)

Sequence (the user had this thread open in the desktop app the whole time)

  1. preview_status({}) → available: false, visible: false, tabId: null.
  2. preview_open({url, open: false}) → available: true, visible: false, tabId: tab_1_… (expected, background only).
  3. preview_open({tabId: tab_1_…, url, open: true}) → same, visible: false. The user reported no panel appeared.
  4. preview_open({url, open: true, reuseExistingTab: false}) → new tab_2_…, visible: false. Still no panel for the user.
  5. preview_status on tab_2 re-read three times over the next ~10 minutes, including after the user signed in to the site in their own browser: visible: false every time, and tabs[] lists only agent-owned tabs.

So this is not just the "status read before the panel connected" timing described above: with an explicit open: true (which sets force: true on the reveal request), the panel never appeared and no viewer ever attached, across two tabs and ten minutes. The tab itself was fine for automation (available: true, navigation and snapshots worked), so the break is between the reveal request and the client opening the surface.

Impact: any flow that needs the human to act in the agent's tab (here, logging in to a Cognito-protected app so the agent can run screen checks) is blocked, since the user cannot reach the tab at all. The agent also has no way to tell "reveal lost" apart from "panel not connected yet".

Happy to collect more if you tell me what to look at (desktop logs, a specific server log line, or a debug build).

Synced from GitHub

Another data point on T3 Code 0.1.3-nightly.20261023.3566, with a Linux server host: preview_open({"open":true}) with no URL returns available:true, visible:false, control.owner:"agent", viewport 1280x800, and mode fill. This adds a newer version and a no-URL call. The returned status alone does not prove the panel was hidden.

Synced from GitHub

Additional reproduction on T3 Code 0.1.2, Linux host (Linux 7.2.8-9-omarchy x86_64), Codex provider. Observed 2026-10-27.

The user confirmed that the browser panel appears but stays blank or connecting. This observation comes from the client UI, not an inference from visible:false. The affected client is the T3 desktop app, confirmed by the user. Its version and operating system have not been captured; 0.1.2 is the verified Linux server runtime version.

Minimal test in a separate thread, using a new incognito tab:

  1. preview_status({}) returned available:false, visible:false, tabId:null.
  2. preview_open({url:"https://example.com", reuseExistingTab:false, show:true, profileId:"incognito"}) returned available:true, visible:false, title Example Domain, loading:false, viewport 1280x800.
  3. preview_snapshot({tabId}) returned the page DOM, HTTP 200 for the document, and no console errors. preview_snapshot({tabId, save:true}) produced a rendered 1280x800 PNG, inspected locally.
  4. preview_open({tabId, open:true, show:true}) and subsequent status calls continued to return visible:false. The preview list showed runtime:"server", successful navigation, reveal:true, and revealRequest.force:true. Its thread ID matched the actual test thread.
  5. The user reported: "Panel appears but stays blank or connecting".
  6. After that report, another saved snapshot succeeded immediately while status remained available:true, loading:false, visible:false.

Expected: opening the panel displays the loaded page, or reports an actionable connection error.

Actual: the user sees a blank/connecting panel while agent DOM reads and screenshots continue to work. This blocks interactive use of the browser from that client. No root cause is established, and the agent did not capture the client's DOM or network trace.

The successful snapshots distinguish this observation from the blocked-capture reproduction in #24852. #19420 also describes a connecting panel, but on a different host/client combination. Adding this here rather than opening another overlapping report.

No MCP transport failure recurred during this test. A prior isolated transport error and a separately resolved malformed URL were excluded from the reproduction.

Verified partial workaround: saved agent screenshots can show read-only page content. No interactive workaround has been verified.