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
- Open a secondary `WebviewWindow` from the main window via Tauri API.
- From the secondary window's JS, after some user action (e.g. form submit),
call `getCurrentWindow().destroy()` synchronously.
- 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).)
Describe the bug
On macOS 26.3 (Tahoe), calling
getCurrentWindow().destroy()(or.close()) ona 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):
The
0x640offset suggests dereference of a member on an already-releasedWebPageProxy(the secondary window's webview), happening while the mainwindow's KVO/inset recalculation runs on the main-thread RunLoop.
Environment
Reproduction
call `getCurrentWindow().destroy()` synchronously.
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).)