[Bug]: preview_resize always times out (and evicts the automation host) when the main window is zoomed, because the guest webview reports innerWidth × hostZoom
Nobody has claimed this yet.
- 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_resizecan 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
- 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.devicePixelRatioin the renderer reads1.577on a non-Retina 1920x2160 display). - From an agent, call
preview_openwith any URL (e.g.https://example.com). - Call
preview_resizewith{ 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, whererenderedViewportcomes fromwebview.executeJavaScript("({ width: window.innerWidth, height: window.innerHeight })")and must match the requested CSS size within 1 px. - The desktop
PreviewManagerasserts the guest zoom factor totab.zoomFactor(defaultbrowserDefaultZoomFactor = 1) onregisterWebviewand again inreapplyZoomwheneverDesktopWindow.zoomMainchanges the main window zoom. - With the embedder at zoom 1.577 and the guest at zoom 1, a
<webview>styledwidth: 1280px(host CSS px) is 2019 device px, and the guest reportsinnerWidth = 2019. Measured on the affected machine:data-preview-css-width = 1280, guestinnerWidth = 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_resizepass and restores correct breakpoints. A proper fix would either compare the rendered viewport in host CSS pixels (divide guestinnerWidthby the embedder zoom factor), or set the guest zoom tobrowserDefaultZoomFactor * mainWindowZoomFactorinassertTabZoom/reapplyZoom.
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/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