Before submitting
Area
apps/server
Summary
In an environment-hosted browser tab, a link with target="_blank" or a window.open() call opens its page in a new background tab. The panel stays on the original page, so from the user's side the click appears to do nothing. The only sign is an extra tab in the tab strip, which is easy to miss in the narrow side panel. The desktop app's native tabs behave differently: target="_blank" loads in the same tab.
Steps to reproduce
- Serve this page somewhere the environment can reach, for example with
python3 -m http.server on the server host:
<a href="https://example.org/" target="_blank">target=_blank link</a>
<button onclick="window.open('https://www.iana.org/')">window.open button</button>
- In a thread on an environment without an attached desktop app (a remote server, or any server opened from the web app), open the Browser panel and go to that page. The tab reports
runtime: "server".
- Click the link, then the button.
Expected behavior
The opened page is in view after the click: either the panel switches to the new tab, as Chrome does for a user-initiated new tab, or the link loads in the current tab, as the desktop app's native tabs do.
Actual behavior
Each click adds a tab ("Example Domain", then "Internet Assigned Numbers Authority") to the strip. The panel keeps showing the original page, and the address bar keeps the original URL.
I reproduced this with real mouse clicks on the streamed tab in the web client, on a dev server built from 72d5c32ba6.
Root cause
- Server: Playwright's
popup event adopts every new window as a new tab. adoptPopup calls manager.open with reveal: false for agent-owned openers and with nothing for human-owned ones. Nothing in the published snapshot says that a tab the user is controlling just opened this one. The opener's id stays server-side in ServerTab.openerTabId, which only the agent status output exposes.
- Client:
reconcileBrowserSurfaces appends a surface for the new session but keeps activeSurfaceId. The only automatic activation is the agent-reveal path, which requires reveal === true.
- Desktop native tabs, by contrast:
previewWindowOpenAction loads target="_blank" (a tab disposition) in the same tab, and opens a real popup window only for window.open with window features. The two runtimes disagree on the same click.
Note that window.open popups must keep their opener alive for OAuth-style flows that postMessage back. That is presumably why server popups become separate tabs, and why simply navigating in place is not a complete fix.
Impact
Major degradation or frequent failure
Version or commit
T3 Code 0.0.46-nightly.20261006.2735. Reproduced on 72d5c32ba6.
Environment
The T3 Code (Nightly) desktop app on macOS 26, connected to a remote t3 serve on Ubuntu 26.04. Reproduced in Chromium against a dev server on the same Linux host. The server uses chrome-headless-shell 154.0.8037.92.
Before submitting
Area
apps/server
Summary
In an environment-hosted browser tab, a link with
target="_blank"or awindow.open()call opens its page in a new background tab. The panel stays on the original page, so from the user's side the click appears to do nothing. The only sign is an extra tab in the tab strip, which is easy to miss in the narrow side panel. The desktop app's native tabs behave differently:target="_blank"loads in the same tab.Steps to reproduce
python3 -m http.serveron the server host:runtime: "server".Expected behavior
The opened page is in view after the click: either the panel switches to the new tab, as Chrome does for a user-initiated new tab, or the link loads in the current tab, as the desktop app's native tabs do.
Actual behavior
Each click adds a tab ("Example Domain", then "Internet Assigned Numbers Authority") to the strip. The panel keeps showing the original page, and the address bar keeps the original URL.
I reproduced this with real mouse clicks on the streamed tab in the web client, on a dev server built from
72d5c32ba6.Root cause
popupevent adopts every new window as a new tab.adoptPopupcallsmanager.openwithreveal: falsefor agent-owned openers and with nothing for human-owned ones. Nothing in the published snapshot says that a tab the user is controlling just opened this one. The opener's id stays server-side inServerTab.openerTabId, which only the agent status output exposes.reconcileBrowserSurfacesappends a surface for the new session but keepsactiveSurfaceId. The only automatic activation is the agent-reveal path, which requiresreveal === true.previewWindowOpenActionloadstarget="_blank"(a tab disposition) in the same tab, and opens a real popup window only forwindow.openwith window features. The two runtimes disagree on the same click.Note that
window.openpopups must keep their opener alive for OAuth-style flows thatpostMessageback. That is presumably why server popups become separate tabs, and why simply navigating in place is not a complete fix.Impact
Major degradation or frequent failure
Version or commit
T3 Code
0.0.46-nightly.20261006.2735. Reproduced on72d5c32ba6.Environment
The T3 Code (Nightly) desktop app on macOS 26, connected to a remote
t3 serveon Ubuntu 26.04. Reproduced in Chromium against a dev server on the same Linux host. The server useschrome-headless-shell154.0.8037.92.