pingdotgg / pingdotgg/t3code

[Bug]: preview_resize always times out (and evicts the automation host) when the main window is zoomed, because the guest webview reports innerWidth × hostZoom

Open
#12,319 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accepted bug via-triage
Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

Filed by Claude (Fable 5.1, running inside T3 Code) on behalf of Gal Hadad (@Gal-WPsite), at his request. Gal reviewed the summary; the investigation and reproduction below were done by the agent on his Mac.

Before submitting
  • I searched existing issues and did not find a duplicate. #12146 and #12273 cover the host being evicted after a timeout; this report is about a deterministic cause of the timeout: preview_resize can never succeed while the main window is zoomed.
  • I included enough detail to reproduce or investigate the problem.
Area

apps/web (preview automation host in the renderer), with a side effect in apps/server

Steps to reproduce
  1. On macOS, in T3 Code (Alpha) 0.0.42, use View > Zoom In a few times so the main window runs at a zoom level other than 0 (Gal runs at level 2.5, i.e. 1.2 ** 2.5 = 1.577; window.devicePixelRatio in the renderer reads 1.577 on a non-Retina 1920x2160 display).
  2. From an agent, call preview_open with any URL (e.g. https://example.com).
  3. Call preview_resize with { mode: "freeform", width: 1440, height: 900 } (any freeform or preset size reproduces).
Expected behavior

The resize completes and the guest reports a 1440x900 CSS viewport, independent of the main window zoom.

Actual behavior

preview_resize blocks for the full timeout and fails with Preview automation resize timed out after 15000ms. Because PreviewAutomationBroker.awaitResponse disconnects the host on timeout, every later preview/device tool then fails with No preview automation host is available for <op> in environment … until the window is reloaded (View > Reload) or closed and reopened (that part is #12146).

Root cause, read from the bundled renderer in app.asar (function names are the minified ones):

  • The renderer's resize handler polls until XU({ setting, appliedSettingKey, declaredViewport, renderedViewport }) is true, where renderedViewport comes from webview.executeJavaScript("({ width: window.innerWidth, height: window.innerHeight })") and must match the requested CSS size within 1 px.
  • The desktop PreviewManager asserts the guest zoom factor to tab.zoomFactor (default browserDefaultZoomFactor = 1) on registerWebview and again in reapplyZoom whenever DesktopWindow.zoomMain changes the main window zoom.
  • With the embedder at zoom 1.577 and the guest at zoom 1, a <webview> styled width: 1280px (host CSS px) is 2019 device px, and the guest reports innerWidth = 2019. Measured on the affected machine: data-preview-css-width = 1280, guest innerWidth = 2019, innerHeight = 1262. The comparison can never pass, so every resize times out.
  • Side effect even without automation: a "1280 px viewport" really lays out the page at 2019 CSS px, so responsive breakpoints shown in the preview are wrong whenever the UI is zoomed.

Verification of the diagnosis: setting the guest zoom to the host zoom from the renderer (webview.setZoomFactor(window.devicePixelRatio) on this dpr-1 display) makes the guest report 1280x800, and the same preview_resize to 1440x900 then succeeds immediately; a preset resize (iphone-12-pro) and mode: "fill" also succeed. Resetting the guest zoom to 1 brings the timeout back.

Impact

Any user who zooms the T3 Code UI (accessibility, high-resolution portrait monitors, non-Latin scripts) loses all preview automation on the first resize, and the failure mode is a 15 s hang followed by a permanent "no host" state, with no hint that the UI zoom is the cause.

Version or commit

T3 Code (Alpha) 0.0.42 (CFBundleVersion 0.0.42), app.asar dated 2026-09-16.

Environment

macOS (Darwin 25.5.0), Apple Silicon, single 1920x2160 display at scale 1. Agent provider: Codex (when first hit) and Claude Code (reproduction). Local environment, no T3 Connect.

Logs or stack traces

server.trace.ndjson, 2026-09-17 (Asia/Jerusalem), same environment id throughout:

23:50:01 PreviewAutomationBroker.connect                       ok
23:50:36 McpServer tools/call preview_resize {tabId:"tab_3",mode:"freeform",width:1440,height:900}
23:50:36 PreviewAutomationBroker.awaitResponse 15002ms         PreviewAutomationTimeoutError: Preview automation resize timed out after 15000ms.
23:50:51 PreviewAutomationBroker.disconnect                    ok
23:50:51 ws.rpc.previewAutomation.connect (50718ms)            Interrupted
23:50:51 PreviewAutomationBroker.invoke status                 PreviewAutomationNoAvailableHostError
23:50:52 PreviewAutomationBroker.invoke resize                 PreviewAutomationNoAvailableHostError
23:51:12 PreviewAutomationBroker.invoke open                   PreviewAutomationNoAvailableHostError

No new PreviewAutomationBroker.connect appears afterwards until the window is reloaded. desktop.trace.ndjson shows no resize-related PreviewManager span in that window; the request never left the renderer's wait loop.

Screenshots, recordings, or supporting files

Renderer state captured over the local DevTools port while the resize was pending:

{"inner":[532,1349],"dpr":1.5774409770965576,"outer":[840,2129],
 "webview":{"key":"freeform:1280:800:","cssW":"1280","cssH":"800","zoomFactor":1,
            "guestInner":{"width":2019,"height":1262}}}
Workaround
  • View > Actual Size (Cmd+0) before using preview automation; then View > Reload if the host is already gone.
  • Gal's local RTL helper now keeps preview webviews' zoom factor equal to the main window zoom (snapped to Electron's half-level steps), which makes preview_resize pass and restores correct breakpoints. A proper fix would either compare the rendered viewport in host CSS pixels (divide guest innerWidth by the embedder zoom factor), or set the guest zoom to browserDefaultZoomFactor * mainWindowZoomFactor in assertTabZoom/reapplyZoom.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/web with the preview automation renderer resize handler and the PreviewManager entry points named in the report, especially assertTabZoom and reapplyZoom; inspect apps/server's PreviewAutomationBroker timeout behavior for the host-eviction side effect. Reproduce preview_resize with the main window zoomed, then verify that freeform and preset resizes complete with the requested CSS viewport and that later preview tools remain available.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, typescript
Domain
desktop-dev, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.