[Opus 5.5][Claude Code] on behalf of SKCarlsson.
Hit again on macOS with #24056 included. The evidence suggests the capture that crashed the app had been stuck for about a day, so the risk lasts longer than "while a screenshot is in flight".
The crash
- Build: packaged
0.1.3-nightly.20261023.3579(Electron 44.9.3), macOS 27.0.1 arm64. The bundle contains #24056's one-screenshot-per-guest queue. - Symbolicated with Electron's v44.9.3 Breakpad symbols (module
4C4C442D55553144A1FC8F505C7CA8700, which matches the crash report). It's the same frame as #24026:
| 1 | CrBrowserMain EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS at 0x0 |
| 2 | #0 content::RenderWidgetHostImpl::OnSnapshotFromSurfaceReceived render_widget_host_impl.cc:3917 |
| 3 | #1 RenderWidgetHostViewChildFrame::CopyFromSurface(...)::$_0 (callback) |
| 4 | #3 base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() |
| 5 | #6 base::MessagePumpCFRunLoopBase::RunWorkSource(void*) |
The faulting instruction is ldr x8, [x21] with x21 = 0 (the null GetView()), followed by a vtable call.
No screenshot was being taken
The retained server traces cover the ~50 minutes before the crash and contain no preview automation calls. The only preview spans are PreviewAutomationBroker.focusHost and PreviewManager.close at 21:05:51.65, after the main process had already died.
The pending capture was probably ~26 hours old
macOS powerd shows the main process holding a "Capturing" NoDisplaySleepAssertion for the whole session:
| 1 | 2026-10-23 19:28:53 preview guest renderer starts (pid 9439, surface "preview" in renderer-history.ndjson) |
| 2 | 2026-10-23 19:29:04 powerd: Created NoDisplaySleepAssertion "Capturing" id:21474876784 |
| 3 | 2026-10-24 21:02:21 guest renderer 9439 still alive (last renderer-history sample) |
| 4 | 2026-10-24 21:05:51 main process SIGSEGV |
| 5 | 2026-10-24 21:05:51 powerd: ClientDied NoDisplaySleepAssertion "Capturing" age:25:36:46 |
In Chromium 152 the only DevTools path that takes this lock is Page.captureScreenshot: IncrementCapturerCount(stay_awake=true) at page_handler.cc:1432. The handle lives in PendingScreenshotRequest until the snapshot callback runs. Page.startScreencast takes no capturer handle, and neither does DevToolsVideoConsumer. Outside DevTools, a tab-capture stream (the getDisplayMedia recording path) holds the same lock. A lock held for 25.6 hours plus a crash in the screenshot callback with no screenshot requested points to one Page.captureScreenshot that stalled on 2026-10-23 and stayed pending until the guest's renderer went away. The desktop and server traces from 19:29 on 2026-10-23 have already rotated out, so I couldn't see which call started it.
What this means for this issue
- The crash can happen long after any screenshot is requested. A stalled capture stays pending indefinitely and crashes the app whenever that guest's renderer exits, here about a day later. #24056's queue lets later screenshots get past a stuck one, but the stuck one stays pending in Chromium until that renderer goes away.
- #17870 and #17180 (leaked "Capturing" wake lock) are probably this same stuck screenshot, not a screencast. While it lasts, the Mac's display can't sleep.
- An app-side check is available: a guest with no screenshot in flight on T3's side whose
webContents.isBeingCaptured()is still true is carrying a stuck capture (untested). - Chromium 152 notes why captures stall, next to the
kCDPScreenshotNewSurfacecheck: "When view is completely hidden, capturing a surface snapshot will stall because the surface is never presented." Not sendingPage.captureScreenshotto a hidden guest, and usingcapturePage()instead, would avoid creating stuck captures until Electron ships Chromium 157.
I couldn't see what ended the guest renderer at 21:05:51 because macOS doesn't log renderer exits. A T3 utility helper exited and T3's audio session stopped about 100 ms before the main process died.