libnyanpasu/clash-nyanpasu · error

window not found

Error message

window not found

What it means

`with_ns_window` calls Tauri's `WebviewWindow::ns_window()` and expects to get the raw `*mut NSWindow`. The panic means Tauri could not return the native macOS window pointer — usually the window is not a real NSWindow-backed window (wrong window type or already destroyed) or the call is made off the main thread. This macOS-only helper then cannot apply traffic-light positioning.

Source

Thrown at backend/tauri/src/window.rs:967

        Ok(())
    }

    #[derive(Debug, Clone)]
    struct WindowState {
        window: WebviewWindow<tauri::Wry>,
        traffic_lights_pos: Position,
    }

    impl WindowState {
        fn new(window: WebviewWindow<tauri::Wry>, traffic_lights_pos: Position) -> Self {
            Self {
                window,
                traffic_lights_pos,
            }
        }

        fn with_ns_window<T>(&self, func: impl FnOnce(Retained<NSWindow>) -> T) -> T {
            let ns_window = self.window.ns_window().expect("window not found");
            let ns_window = unsafe { Retained::retain_autoreleased(ns_window as *mut NSWindow) }
                .expect("failed to retain window");
            func(ns_window)
        }

        fn apply_traffic_lights_pos(&self) {
            self.with_ns_window(|win| {
                set_traffic_lights_pos(win, self.traffic_lights_pos)
                    .expect("failed to set traffic lights pos");
            });
        }
    }

    #[derive(Debug)]
    struct TrafficLightsWindowDelegateIvars {
        app_box: WindowState,
        super_class: Retained<ProtocolObject<dyn NSWindowDelegate>>,
    }

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Check that the window still exists (e.g. `get_webview_window` returns Some) before calling `with_ns_window`, and skip silently otherwise.
  2. Dispatch all NSWindow access to the main thread (`MainThreadMarker`/`performOnMainThread`) as required by AppKit.
  3. Guard the call against the window-closing state (e.g. skip traffic-light work in delegate callbacks after close).
  4. Replace `.expect` with a `Result` return so callers can degrade instead of panicking.

Example fix

// before
let ns_window = self.window.ns_window().expect("window not found");
// after
let Ok(ns_window) = self.window.ns_window() else {
    tracing::warn!("ns_window unavailable; skipping traffic light update");
    return Default::default();
};
Defensive patterns

Strategy: fallback

Validate before calling

if window.as_ref().map(|w| w.is_visible()).unwrap_or(false) != true {
    tracing::warn!("window gone or hidden; skipping ns_window access");
}

Type guard

fn has_ns_window(window: &WebviewWindow) -> bool {
    window.is_visible().unwrap_or(false)
        && window.ns_window().is_ok()
}

Try / catch

let Ok(ns_window) = self.window.ns_window() else {
    tracing::warn!("ns_window unavailable; skipping");
    return Default::default();
};

Prevention

When it happens

Trigger: Calling `apply_traffic_lights_pos`/`with_ns_window` on a window whose underlying platform window is gone (window closed/closing during a callback), a window created as a non-NSWindow type, or `ns_window()` invoked outside the main thread.

Common situations: Traffic-light position restoration racing window close during app shutdown or workspace switching; delegate callbacks firing after `window.close()`; running logic on a background thread without dispatching to the main thread.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/515e58764fb0f4d7. Report an issue: GitHub.