tauri-apps/tauri · error
view to be installed in window
Error message
view to be installed in window
What it means
On macOS, Window::ns_window() (also reached via WebviewWindow::ns_window, which delegates to it) obtains the raw window handle, casts the backing NSView, then calls view.window().expect("view to be installed in window"). NSView.window() returns None while the view is not attached to any NSWindow, so this panic means the AppKit handle was fetched before the view was installed into a real window (or after it was detached). It is macOS-only and escapes the API's Result-based error handling because it is an internal expect, not an Err.
Source
Thrown at crates/tauri/src/window/mod.rs:1654
.window
.dispatcher
.available_monitors()
.map(|m| m.into_iter().map(Into::into).collect())
.map_err(Into::into)
}
/// Returns the native handle that is used by this window.
#[cfg(target_os = "macos")]
pub fn ns_window(&self) -> crate::Result<*mut std::ffi::c_void> {
self
.window
.dispatcher
.window_handle()
.map_err(Into::into)
.and_then(|handle| {
if let raw_window_handle::RawWindowHandle::AppKit(h) = handle.as_raw() {
let view: &objc2_app_kit::NSView = unsafe { h.ns_view.cast().as_ref() };
let ns_window = view.window().expect("view to be installed in window");
Ok(objc2::rc::Retained::autorelease_ptr(ns_window).cast())
} else {
Err(crate::Error::InvalidWindowHandle)
}
})
}
/// Returns the pointer to the content view of this window.
#[cfg(target_os = "macos")]
pub fn ns_view(&self) -> crate::Result<*mut std::ffi::c_void> {
self
.window
.dispatcher
.window_handle()
.map_err(Into::into)
.and_then(|handle| {
if let raw_window_handle::RawWindowHandle::AppKit(h) = handle.as_raw() {
Ok(h.ns_view.as_ptr())View on GitHub (pinned to 52e4b6e71d)
Solutions
- Defer the call until the window is realized: read ns_window() after show(), inside on_window_event for the first Focused/Resized event, or from RunEvent::Ready in app.run.
- If it still panics after deferral, upgrade tauri and wry — view-installation timing regressions have been fixed across releases — and report with a minimal repro.
- Prefer ns_view() and resolve the window yourself via objc2's Option-returning NSView::window() when you must tolerate a not-yet-attached view.
- Ensure the call is compiled and executed only on macOS and against a live (not closed) window.
Example fix
// before: called right after build — NSView not yet installed, panics
let w = WebviewWindowBuilder::new(&app, "main", WebviewUrl::default()).build()?;
let raw = w.ns_window()?; // expect("view to be installed in window")
// after: wait until the window is attached before taking the handle
let w = WebviewWindowBuilder::new(&app, "main", WebviewUrl::default()).build()?;
w.show()?;
let w2 = w.clone();
w.on_window_event(move |e| {
if matches!(e, tauri::WindowEvent::Focused(true)) {
if let Ok(raw) = w2.ns_window() {
// view is installed; safe to use the NSWindow pointer
}
}
}); Defensive patterns
Strategy: validation
Validate before calling
// Only fetch the AppKit handle once the window is realized;
// a visible window implies its NSView is installed in an NSWindow
if window.is_visible().unwrap_or(false) {
let raw = window.ns_window()?;
// use raw
} Prevention
- Never call ns_window() immediately after build() in setup; defer to after show(), the first Focused/Resized window event, or RunEvent::Ready.
- Keep the call behind #[cfg(target_os = 'macos')] and only invoke it on a live window.
- If the not-attached case must be tolerated, use ns_view() plus objc2's Option-returning NSView::window() instead of the built-in expect.
- After upgrading tauri/wry, re-test early handle acquisition — view-installation timing has shifted between releases.
When it happens
Trigger: Calling ns_window() immediately after WebviewWindowBuilder::build / WindowBuilder::build (e.g. inside setup, before the event loop attaches the content view); calling it before the window was ever shown/focused; calling it on a window being torn down; or a wry/tao timing change where window_handle() returns a view that is not yet in the view hierarchy.
Common situations: Setup code that grabs NSWindow pointers for AppKit customization (titlebar styling, NSWindowDelegate, blur) and runs too early; apps that regressed after upgrading tauri/wry because handle-availability timing shifted; intermittent failures on slower machines where window construction has not finished.
Related errors
- `Window::set_enabled` can only be called on the main thread
- poisoned window resources table
- poisoned window
- failed to read plist {}: {}
- Invalid SDK root {}
AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20).
Data as JSON: /api/errors/15c627e8fc1d1b08.
Report an issue: GitHub.