Skip to content

[bug] macOS 26.3 SIGSEGV in WebKit::WebPageProxy::dispatchSetObscuredContentInsets() after destroying a secondary webview window #1730

@ni-byeongju

Description

@ni-byeongju

Describe the bug

On macOS 26.3 (Tahoe), calling getCurrentWindow().destroy() (or .close()) on
a secondary webview window from within that window's JS context — typically
right after the user saves a form and the window auto-closes — crashes the
entire app with SIGSEGV in WebKit's main-thread RunLoop work, while the main
window is being re-activated as the key window.

Stack trace (Thread 0, main / com.apple.main-thread):

0  WebKit          WebKit::WebPageProxy::dispatchSetObscuredContentInsets() + 324
1  JavaScriptCore  WTF::RunLoop::performWork() + 552
2  JavaScriptCore  WTF::RunLoop::performWork(void*) + 36
3  CoreFoundation  __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
…
20 tao             tao::platform_impl::platform::event_loop::EventLoop::run_return
21 tao             tao::platform_impl::platform::event_loop::EventLoop::run
22 tao             tao::event_loop::EventLoop::run
23 tauri-runtime-wry  <_ as tauri_runtime::Runtime>::run
24 tauri           tauri::app::App::run

Exception Type:    EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000640

The 0x640 offset suggests dereference of a member on an already-released
WebPageProxy (the secondary window's webview), happening while the main
window's KVO/inset recalculation runs on the main-thread RunLoop.

Environment

  • macOS: 26.3 (25D125), Apple Silicon (Mac14,12)
  • tauri: 2.11.0
  • wry: 0.55.0
  • tao: 0.35.0
  • webview backend: WKWebView (system WebKit)

Reproduction

  1. Open a secondary `WebviewWindow` from the main window via Tauri API.
  2. From the secondary window's JS, after some user action (e.g. form submit),
    call `getCurrentWindow().destroy()` synchronously.
  3. The main window regains key-window focus and the app SIGSEGVs on the next
    main-thread RunLoop tick.

The crash does not reproduce if the secondary window is first hidden and
the destroy is deferred to a later macrotask — see workaround below.

Workaround

Hide the window first, give the main-thread RunLoop time to complete the
obscured-insets recalculation against the still-alive WKWebView, then destroy:

```ts
const win = getCurrentWindow();
void win.hide().finally(() => {
setTimeout(() => { void win.destroy(); }, 200);
});
```

Applying this to every close path of the secondary window (explicit save,
explicit cancel, and `onCloseRequested` for OS-level X / Cmd+W) eliminates the
crash in our app.

Why I'm reporting this here

This is almost certainly a WebKit regression on macOS 26.3 — `wry`/`tauri`
aren't calling `dispatchSetObscuredContentInsets` directly. But the trigger
path (`tao::EventLoop::run_return` → main-thread RunLoop → WebKit obscured
insets dispatch on a released `WebPageProxy`) is reachable from any wry/tauri
app that uses multiple windows on macOS, so a wry-side workaround (e.g.
draining `WKWebView` from its parent NSWindow before close, or deferring
destroy by one RunLoop tick) might be worth considering. I haven't found this
exact signature in `tauri-apps/wry` / `tauri-apps/tauri` / `tauri-apps/tao`
issues — apologies if I missed a duplicate.

(Related but distinct macOS 26 reports: #1576 `addUserInstalledFontURLs`,
#1705 `build_as_child` (fixed in 0.55.0).)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions