tauri-apps/tauri · error

Not an IconMenuItem

Error message

Not an IconMenuItem

What it means

MenuItemKind::as_icon_menuitem_unchecked casts a menu item handle to an IconMenuItem reference. It panics when the underlying item is actually a MenuItem, Submenu, PredefinedMenuItem or CheckMenuItem rather than an icon item, because the '_ => panic!()' catch-all arm is reached.

Solutions

  1. Check the kind first with a match on MenuItemKind::Icon before casting
  2. Use as_icon_menuitem (the checked variant returning Result) instead of the unchecked variant
  3. Trace where the MenuItemKind came from and construct it as IconMenuItem::with_id

Example fix

// before
let icon_item = item.as_icon_menuitem_unchecked();
// after
let icon_item = match item.kind() {
  MenuItemKind::Icon(i) => i,
  _ => anyhow::bail!("expected an IconMenuItem"),
};
Defensive patterns

Strategy: type-guard

Validate before calling

fn as_icon(item: &MenuItemKind<R>) -> Option<&IconMenuItem<R>> {
  match item { MenuItemKind::Icon(i) => Some(i), _ => None }
}

Type guard

fn is_icon_menu_item<R: Runtime>(k: &MenuItemKind<R>) -> bool {
  matches!(k, MenuItemKind::Icon(_))
}

Try / catch

std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| item.as_icon_menuitem_unchecked()))
  .map_err(|_| anyhow::anyhow!("item is not an IconMenuItem"))

Prevention

When it happens

Trigger: Calling as_icon_menuitem_unchecked on a MenuItemKind obtained from an event, menu iteration, or from building a menu with MenuBuilder, where the item was created as a plain MenuItem or Submenu instead of IconMenuItem::with_id.

Common situations: Storing heterogeneous MenuItemKind values in a Vec and assuming they are all icon items; dynamically populating menus from config and blindly downcasting; copy-pasting unchecked-cast code after switching the item constructor.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/70a9038d7f77ac90. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri/src/menu/mod.rs:673

    match self {
      MenuItemKind::Check(i) => i,
      _ => panic!("Not a CheckMenuItem"),
    }
  }

  /// Casts this item to a [`IconMenuItem`], and returns `None` if it wasn't.
  pub fn as_icon_menuitem(&self) -> Option<&IconMenuItem<R>> {
    match self {
      MenuItemKind::Icon(i) => Some(i),
      _ => None,
    }
  }

  /// Casts this item to a [`IconMenuItem`], and panics if it wasn't.
  pub fn as_icon_menuitem_unchecked(&self) -> &IconMenuItem<R> {
    match self {
      MenuItemKind::Icon(i) => i,
      _ => panic!("Not an IconMenuItem"),
    }
  }
}

impl<R: Runtime> Clone for MenuItemKind<R> {
  fn clone(&self) -> Self {
    match self {
      Self::MenuItem(i) => Self::MenuItem(i.clone()),
      Self::Submenu(i) => Self::Submenu(i.clone()),
      Self::Predefined(i) => Self::Predefined(i.clone()),
      Self::Check(i) => Self::Check(i.clone()),
      Self::Icon(i) => Self::Icon(i.clone()),
    }
  }
}

impl<R: Runtime> sealed::IsMenuItemBase for MenuItemKind<R> {
  fn inner_muda(&self) -> &dyn muda::IsMenuItem {

View on GitHub (pinned to 460ec35447)