slint-ui/slint · error

It must be there because we set the global

Error message

It must be there because we set the global

What it means

During `show_popup`, after instantiating the popup component Slint calls `window_adapter(false, ...)` on the popup's item tree; because the global window adapter was already set on the popup tree at that point, the Option is expected to be Some. The expect fires if the popup's item tree has no window adapter — meaning the setup step that assigns the adapter to the popup component did not happen.

Solutions

  1. Always show popups through the public API (`show_popup` / `PopupWindow`) so the window adapter is set on the popup tree first
  2. When writing a custom backend, ensure `window_adapter(true, ...)` (or the global adapter assignment) runs on the popup item tree before this code path
  3. Verify with a debug assert that the popup component was instantiated against the parent window's adapter

Example fix

// before
let tree = popup_def.create(&ctx)?; // never attached to a window adapter
window.show_popup(&tree, ...); // panics
// after
let tree = popup_def.create_with_window_adapter(&parent_adapter, &ctx)?;
window.show_popup(&tree, ...);
Defensive patterns

Strategy: validation

Validate before calling

// confirm the popup tree has a window adapter before showing
let mut adapter = None;
ItemTreeRc::borrow_pin(&popup_tree).as_ref().window_adapter(false, &mut adapter);
assert!(adapter.is_some(), "popup item tree has no window adapter");

Type guard

fn popup_has_adapter(tree: &ItemTreeRc) -> bool {
    let mut a = None;
    ItemTreeRc::borrow_pin(tree).as_ref().window_adapter(false, &mut a);
    a.is_some()
}

Try / catch

std::panic::catch_unwind(AssertUnwindSafe(|| window.show_popup(&popup_tree, pos, true))).map_err(|_| PopupError::NoWindowAdapter)

Prevention

When it happens

Trigger: Showing a popup when the popup component's item tree was created without being attached to a window adapter — e.g. manual popup instantiation through the interpreter/FFI bypassing the normal show_popup setup, or backend code constructing popups out of order.

Common situations: Custom backend/window-adapter development; interpreter-driven apps that create popup item trees directly instead of going through `show_popup`; race/ordering bugs in embedded backends without dedicated popup window support.

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@3a7e700487 (2026-09-16). Data as JSON: /api/errors/4b25197ed0792d82. Report an issue: GitHub.

Appendix: source

Thrown at internal/core/window.rs:2129

            .borrow()
            .iter()
            .find(|p| ItemTreeRc::ptr_eq(&p.component, &parent_root_item_tree))
        {
            // Popup in a popup
            match &parent_popup.location {
                PopupWindowLocation::TopLevel(wa) => wa.clone(),
                PopupWindowLocation::ChildWindow(_) => self.window_adapter(),
            }
        } else {
            self.window_adapter()
        };

        let popup_window_adapter = {
            let mut popup_window_adapter = None;
            ItemTreeRc::borrow_pin(popup_componentrc)
                .as_ref()
                .window_adapter(false, &mut popup_window_adapter);
            popup_window_adapter.expect("It must be there because we set the global")
        };

        // If the window adapter of the popup window and the parent window are equal, create a ChildWindow
        // because we weren't able to create a dedicated popup adapter (for example if the backend does not support it).
        let (location, properties_tracker) =
            if Rc::ptr_eq(&parent_window_adapter, &popup_window_adapter) {
                // Tooltips may extend past the window (e.g. above/left of the anchor); do not clamp.
                let clip_region = Some(LogicalRect::new(
                    LogicalPoint::new(0.0 as crate::Coord, 0.0 as crate::Coord),
                    self.window_adapter().size().to_logical(self.scale_factor()).to_euclid(),
                ));
                let rect = popup::place_popup(
                    popup::Placement::Fixed(LogicalRect::new(position, size)),
                    &clip_region,
                );
                self.window_adapter().request_redraw();
                (
                    PopupWindowLocation::ChildWindow(rect.origin),

View on GitHub (pinned to 3a7e700487)