slint-ui/slint · error

context menus should always have a menu

Error message

context menus should always have a menu

What it means

On Windows, `show_context_menu` displays the muda menu via `show_context_menu_for_hwnd`. The wrapper struct is built with a menu attached, so `menu` should never be `None` here; if it is, an internal invariant is broken and the code panics.

Solutions

  1. Retry the call to confirm it is not a one-off setup race; ensure a valid menu/MenuItem list was passed
  2. Check that you are not mixing slint-internal menu APIs with direct muda usage
  3. Update to the latest slint version and report a bug with a reproducer if it persists
Defensive patterns

Strategy: try-catch

Try / catch

std::panic::catch_unwind(|| window.show_context_menu(position, &menu))
    .map_err(|_| anyhow!("context menu display failed on this platform"))?;

Prevention

When it happens

Trigger: Calling `Window::show_context_menu()` on Windows when the internal `muda::Menu` was not constructed or was taken before display - an internal state inconsistency.

Common situations: Library-internal inconsistency; misuse of internal menu wrappers; version mismatch between slint internals; a bug when the context menu setup failed silently earlier.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/ca104e1003a6ab21. Report an issue: GitHub.

Appendix: source

Thrown at internal/backends/winit/muda.rs:94

        context_menu: &vtable::VRc<MenuVTable>,
        winit_window: &Window,
        position: LogicalPosition,
        proxy: EventLoopProxy<SlintEvent>,
    ) -> Option<Self> {
        install_event_handler_if_necessary(proxy);

        let mut s = Self { entries: Default::default(), tracker: None, menu: None };
        s.rebuild_menu(winit_window, Some(context_menu), MudaType::Context);

        match winit_window.window_handle().ok()?.as_raw() {
            #[cfg(target_os = "windows")]
            RawWindowHandle::Win32(handle) => {
                let position = i_slint_core::api::WindowPosition::Logical(position);
                let position = crate::winitwindowadapter::position_to_winit(&position);
                unsafe {
                    s.menu
                        .as_ref()
                        .expect("context menus should always have a menu")
                        .show_context_menu_for_hwnd(handle.hwnd.get(), Some(position));
                }
                Some(s)
            }
            #[cfg(target_os = "macos")]
            RawWindowHandle::AppKit(handle) => {
                // muda assumes a non-flipped NSView and flips Y internally. But winit's view
                // has isFlipped=true, so we pre-flip Y to compensate.
                let h =
                    winit_window.inner_size().to_logical::<f64>(winit_window.scale_factor()).height;
                let position = Some(winit::dpi::Position::Logical(
                    winit::dpi::LogicalPosition::new(position.x as f64, h - position.y as f64),
                ));
                unsafe {
                    s.menu
                        .as_ref()
                        .expect("context menus should always have a menu")
                        .show_context_menu_for_nsview(handle.ns_view.as_ptr(), position)

View on GitHub (pinned to bb937076de)