Repository navigation
[Bug]: Desktop Browser automation errors lose their type over IPC and report as 'failed on client' #15336
Description
Activity
Note
Grok responding on behalf of Julius.
Triage
Thanks for tracking this down, @PixPMusic! I can confirm it. Desktop preview automation builds typed failures in
apps/desktop/src/preview/Manager.ts(PreviewAutomationTimeoutError,PreviewAutomationInvalidSelectorError,PreviewAutomationTargetNotEditableError, and others), andapps/desktop/src/ipc/DesktopIpc.tsreturns them by rejecting theipcMain.handlepromise. Electron'sipcRenderer.invokekeeps only theErrormessage(see electron#24427), so_tagand the other fields never reach the renderer.PreviewAutomationOperationError.fromCauseinapps/web/src/components/preview/previewAutomationErrors.tsonly keeps a value that's already a host error, or a plain object whose_tagisPreviewAutomationTargetNotEditableError. A thrown desktop error matches neither, so it becomesPreviewAutomationOperationError, whoseresponseTagisPreviewAutomationExecutionError.serializePreviewAutomationHostErroralso dropscause, so the desktop message is gone before it reaches the wire.classifyResponseErrorinapps/server/src/mcp/PreviewAutomationBroker.tshandles the timeout, invalid-selector, and not-editable tags, but the desktop host never sends them. It falls through to the default branch, which is the trace you pasted.Two details affect the fix, though not the diagnosis:
- Keeping
_tagacross IPC wouldn't be enough for timeout or invalid selector. Those desktop classes aren't in the host-error union, andfromCausedoesn't match them by shape. Only the not-editable case is rehydrated, and its test passes a plain object rather than an Electron rejection. preview_clickwith a selector that matches nothing raisesPreviewAutomationTargetNotFoundError. There's no public tag for that, or for coordinates outside the viewport, so those would stayPreviewAutomationExecutionErroreven once the existing tags survive IPC.
On current
main, an unmatchedpreview_wait_forusually doesn't show this yet. The broker'sEffect.timeoutOption(timeoutMs)fires first, returns the "timed out" error, and evicts the host (the open #12898, also reported as #15335, with an open fix attempt in #12899). Immediate desktop failures like an invalid selector or a non-editable target already come back as the generic client error today.Likely fix area
- One option is for the desktop side to return a serializable failure payload (tag plus fields) over IPC, and for the renderer to map it onto the response tags the broker already classifies.
- Adding public tags for target-not-found and out-of-viewport could be considered separately.
A maintainer will decide on the fix direction.
- Keeping
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Oct 3, 2026 Cross-linking related work: #3714 is the
clicktarget-not-found case of this same IPC loss, and #7301 sends a typed click outcome across IPC for that path. This issue covers the desktop tags that already have public counterparts (waitFortimeouts, invalid selectors, non-editable targets). Once #12899 lands, unmatchedpreview_wait_forcalls will start hitting it too: on a real desktop the host's timeout reply arrives and readswaitFor failed on client …instead oftimed out(observed on two Macs; details on #12899).Obsolete since #15328: preview automation no longer runs in the desktop app, so errors no longer cross IPC. The server host returns typed errors directly.
Before submitting
Area
apps/desktop
Steps to reproduce
preview_open).preview_wait_forwith text that never appears and a shorttimeoutMs, or runpreview_clickwith a selector that matches nothing.Expected behavior
The agent sees a typed failure:
Preview automation waitFor timed out after …ms, or the invalid-selector / non-editable-target error, which carry specific guidance.Actual behavior
The agent sees a generic
Preview automation waitFor failed on client preview-…(orclick failed on client …).Automation operations that run in the desktop main process (
apps/desktop/src/preview/Manager.ts:waitFor,click,type, …) fail with typed errors such asPreviewAutomationTimeoutError,PreviewAutomationInvalidSelectorError, andPreviewAutomationTargetNotEditableError. Those failures reach the renderer throughipcRenderer.invoke. Electron rejectsinvokewith a plainErrorcarrying only a message, so_tagand the other fields are lost. The renderer then wraps the error inPreviewAutomationOperationError.fromCause(apps/web/src/components/preview/previewAutomationErrors.ts). It no longer matches a known host error, so it's reported to the server asPreviewAutomationExecutionError. The server'sclassifyResponseErroralready handlesPreviewAutomationTimeoutError,PreviewAutomationInvalidSelectorError, andPreviewAutomationTargetNotEditableError, but those tags never arrive from desktop-side operations.Until now, a
wait_fortimeout usually still read "timed out" by accident: the server's own deadline fired first and produced the timeout error (see #15335). With that race fixed, the host's real answer arrives and shows up as "failed on client".Impact
Minor bug or occasional failure
Version or commit
main @ fffe6e6
Environment
macOS 26, T3 Code Desktop dev build and Nightly 0.0.46-nightly.20261003.2632; Codex provider
Logs or stack traces
# dev server trace, preview_wait_for with timeoutMs 2000 that did not match PreviewToolkit.invoke Failure PreviewAutomationExecutionError: Preview automation waitFor failed on client preview-c94c30600ad9bb3affc165451e0feb7f.