pingdotgg / pingdotgg/t3code

[Bug]: Desktop main process SIGTRAPs during preview_open webview attach / debugger.attach

Open
#8,332 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Before submitting
  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.
Area

apps/desktop

Steps to reproduce

Not a guaranteed crash (race). Observed sequence on macOS desktop:

  1. Desktop app has been running for hours, window in the background.
  2. Agent calls preview_status. Host is connected, but there is no tab yet: available=true, visible=false, tabId=null.
  3. Agent calls preview_open with an HTTPS URL (in this case a third-party login/deep-control page). That creates a new Loading session and mounts a <webview src=url> (including offscreen).
  4. Renderer registers the guest from did-attach / dom-ready via previewBridge.registerWebview.
  5. Main-process PreviewManager.registerWebview mutates the guest (zoom/mute/listeners) and runForks restoreControlSessionwc.debugger.attach("1.3") without waiting and without an isDestroyed() / generation gate.
  6. Overlay wait treats automation.status available=true as soon as the WebContents exists, which is before CDP attach finishes.

Related: #8221 is a generic macOS 26 periodic crash with no stack. This report is a specific CrBrowserMain SIGTRAP tied to preview open.

Expected behavior

preview_open should either succeed or return a typed automation error. The Electron main process should not abort.

Actual behavior

Main process dies with EXC_BREAKPOINT (SIGTRAP) on Thread 0 CrBrowserMain. The in-flight MCP preview_open then surfaces as:

Preview automation client <id> disconnected during open.

(PreviewAutomationClientDisconnectedError — the host stream is dropped because the app died, not because the broker race itself SIGTRAPs.)

The app relaunches afterward. The disconnect/open broker race is JS-only and is already tested; it cannot fatal-check Electron by itself.

Impact

Blocks work completely

(Hard abort of the whole desktop app, including the bundled server. Intermittent, but any cold preview_open of a new HTTPS guest can hit it.)

Version or commit

Desktop 0.0.34, Electron 41.5.0. Preview manager at fe281c540 (fix(desktop): throttle hidden preview rendering (#7445)). Captured on a personal-branded Mac build; the crashing preview attach / CDP path is unmodified upstream desktop code.

Environment

macOS 26.2 (25C56), Apple Silicon (MacBookAir10,1), T3 Code desktop wrapping the shared web client. Crash Role was Background. Process had been up ~8.6 hours.

Logs or stack traces
Exception Type:    EXC_BREAKPOINT (SIGTRAP)
Triggered by Thread: 0  CrBrowserMain
Termination Reason:  Namespace SIGNAL, Code 5, Trace/BPT trap: 5

Reliable frames (Electron Framework is stripped; large +NNNN offsets are neighboring names):
  NSApplication run
  → Electron main loop
  → node::InternalMakeCallback
  → v8::Function::Call
  → immediate crash

No Application Specific Information / CHECK text in the macOS report.

Full sanitized macOS crash report (personal bundle id removed):
https://gist.github.com/bald-ai/3d8c2a7a5d425fe743c26216ca8ffc75

Investigation (source, not a patch)

Proven:

  • Cold preview_open with a URL creates a Loading snapshot (apps/server/src/preview/Manager.ts) and ElectronBrowserHost mounts a <webview> for every session, including offscreen (apps/web/src/browser/HostedBrowserWebview.tsx).
  • Registration runs on did-attach (GuestView still attaching).
  • apps/desktop/src/preview/Manager.ts registerWebviewUnlocked calls setZoomFactor / setAudioMuted / attachListeners, then runFork(restoreControlSession).
  • ensureControlSession / restoreControlSession call debugger.attach("1.3") with no isDestroyed() check. attempt() only catches thrown JS; Chromium CHECK/ImmediateCrash is SIGTRAP on arm64.
  • Overlay available is “guest exists”, not “CDP attached” (automationStatus).
  • setWindowOpenHandler denies popups and loadURLs them into the same guest, which can navigate during attach.
  • PreviewAutomationClientDisconnectedError is raised when the host stream is removed (apps/server/src/mcp/PreviewAutomationBroker.ts). Automation subscriptions use idleTtlMs: 0.

Inferred (high): the SIGTRAP is a GuestView / DevToolsAgentHost fatal check during attach or a concurrent loadURL/setZoomFactor/debugger.attach. Exact CHECK name unknown (stripped symbols).

The broker disconnect-during-open path does not SIGTRAP. The guest-open work running at the same time can.

Likely smallest fix (not implemented here): gate debugger.attach / sendCommand / setZoomFactor / loadURL on !wc.isDestroyed() + current tab generation; await control-session attach under the tab lifecycle lock instead of runFork. Registering only on dom-ready, or attaching CDP lazily on first command that needs it, would also shrink the window. Retrying preview_open on ClientDisconnectedError would not stop the abort.

Workaround

Avoid preview_open of a new tab to an HTTPS login/redirect-heavy URL while the desktop window is in the background. Reusing an already-attached tab is much less likely to hit this. After a crash, relaunch and continue; no evidence this corrupts the sqlite store, but that is not proven.

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/desktop/src/preview/Manager.ts at registerWebviewUnlocked, ensureControlSession, and restoreControlSession; then trace the Loading-session and webview lifecycle in apps/server/src/preview/Manager.ts and apps/web/src/browser/HostedBrowserWebview.tsx. Reproduce the preview_open attach race on macOS and inspect the debugger, navigation, and guest lifecycle operations. Done means the app no longer aborts and preview_open returns a typed automation error when the guest lifecycle changes.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.