{"record":{"id":"15c627e8fc1d1b08","repo":"tauri-apps/tauri","slug":"view-to-be-installed-in-window","errorCode":null,"errorMessage":"view to be installed in window","messagePattern":"view to be installed in window","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri/src/window/mod.rs","lineNumber":1654,"sourceCode":"      .window\n      .dispatcher\n      .available_monitors()\n      .map(|m| m.into_iter().map(Into::into).collect())\n      .map_err(Into::into)\n  }\n\n  /// Returns the native handle that is used by this window.\n  #[cfg(target_os = \"macos\")]\n  pub fn ns_window(&self) -> crate::Result<*mut std::ffi::c_void> {\n    self\n      .window\n      .dispatcher\n      .window_handle()\n      .map_err(Into::into)\n      .and_then(|handle| {\n        if let raw_window_handle::RawWindowHandle::AppKit(h) = handle.as_raw() {\n          let view: &objc2_app_kit::NSView = unsafe { h.ns_view.cast().as_ref() };\n          let ns_window = view.window().expect(\"view to be installed in window\");\n          Ok(objc2::rc::Retained::autorelease_ptr(ns_window).cast())\n        } else {\n          Err(crate::Error::InvalidWindowHandle)\n        }\n      })\n  }\n\n  /// Returns the pointer to the content view of this window.\n  #[cfg(target_os = \"macos\")]\n  pub fn ns_view(&self) -> crate::Result<*mut std::ffi::c_void> {\n    self\n      .window\n      .dispatcher\n      .window_handle()\n      .map_err(Into::into)\n      .and_then(|handle| {\n        if let raw_window_handle::RawWindowHandle::AppKit(h) = handle.as_raw() {\n          Ok(h.ns_view.as_ptr())","sourceCodeStart":1636,"sourceCodeEnd":1672,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri/src/window/mod.rs#L1636-L1672","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: called right after build — NSView not yet installed, panics\nlet w = WebviewWindowBuilder::new(&app, \"main\", WebviewUrl::default()).build()?;\nlet raw = w.ns_window()?; // expect(\"view to be installed in window\")\n\n// after: wait until the window is attached before taking the handle\nlet w = WebviewWindowBuilder::new(&app, \"main\", WebviewUrl::default()).build()?;\nw.show()?;\nlet w2 = w.clone();\nw.on_window_event(move |e| {\n  if matches!(e, tauri::WindowEvent::Focused(true)) {\n    if let Ok(raw) = w2.ns_window() {\n      // view is installed; safe to use the NSWindow pointer\n    }\n  }\n});","handlingStrategy":"validation","validationCode":"// Only fetch the AppKit handle once the window is realized;\n// a visible window implies its NSView is installed in an NSWindow\nif window.is_visible().unwrap_or(false) {\n  let raw = window.ns_window()?;\n  // use raw\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["macos","appkit","nsview","native-handle","panic","window"],"backgroundTag":"missing-native-window-handle","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}