{"record":{"id":"b593e805d122be61","repo":"glzr-io/glazewm","slug":"invalid-tray-menu-event","errorCode":null,"errorMessage":"Invalid tray menu event: {}","messagePattern":"Invalid tray menu event: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/wm/src/sys_tray.rs","lineNumber":55,"sourceCode":"      }\r\n      TrayMenuId::RunOnStartup => write!(f, \"run_on_startup\"),\r\n      TrayMenuId::Exit => write!(f, \"exit\"),\r\n    }\r\n  }\r\n}\r\n\r\nimpl FromStr for TrayMenuId {\r\n  type Err = anyhow::Error;\r\n\r\n  fn from_str(event: &str) -> Result<Self, Self::Err> {\r\n    match event {\r\n      \"show_config_folder\" => Ok(Self::ShowConfigFolder),\r\n      \"reload_config\" => Ok(Self::ReloadConfig),\r\n      #[cfg(target_os = \"windows\")]\r\n      \"toggle_window_animations\" => Ok(Self::ToggleWindowAnimations),\r\n      \"run_on_startup\" => Ok(Self::RunOnStartup),\r\n      \"exit\" => Ok(Self::Exit),\r\n      _ => anyhow::bail!(\"Invalid tray menu event: {}\", event),\r\n    }\r\n  }\r\n}\r\n\r\npub struct SystemTray {\r\n  pub config_reload_rx: mpsc::UnboundedReceiver<()>,\r\n  pub exit_rx: mpsc::UnboundedReceiver<()>,\r\n  _icon_thread: Option<std::thread::JoinHandle<()>>,\r\n  _tray_icon: ThreadBound<TrayIcon>,\r\n}\r\n\r\nimpl SystemTray {\r\n  /// Install the system tray on the main thread after the run loop starts.\r\n  pub fn new(\r\n    config_path: &Path,\r\n    dispatcher: Dispatcher,\r\n  ) -> anyhow::Result<Self> {\r\n    let (exit_tx, exit_rx) = mpsc::unbounded_channel();\r","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/glzr-io/glazewm/blob/5709ad0a3c7c386bbc3e38166a865ffc12937515/packages/wm/src/sys_tray.rs#L37-L73","documentation":"`SystemTrayEvent::from_str` parses menu-item IDs that the system tray sends back over an mpsc channel. Each known ID maps to an enum variant; any unrecognized string (typo, stale ID, event from a different version, or corrupt payload) fails to parse and bails with the raw event text. The library only accepts the exact set of menu IDs it registered.","triggerScenarios":"A tray menu click produces an ID string not present in the match arms — e.g. `\"show_config_folderx\"`, an ID added by a plugin/newer build, or a malformed message delivered on the tray event channel.","commonSituations":"Running mismatched versions of the tray/IPC components (config referencing a menu item that no longer exists); typos when adding new menu items; custom builds where menu IDs were renamed without updating both sides.","solutions":["Check the event string in the error message against the supported IDs (show_config_folder, reload_config, toggle_window_animations, run_on_startup, exit) and use an exact match.","Update GlazeWM/config so both sides agree on the menu item IDs.","If adding a new tray item, add a matching arm in `from_str` and register the same ID when building the menu.","Clear stale tray state (restart the app) so old registered menu IDs are not replayed."],"exampleFix":"// before\ntray.add_menu_item(\"reload-conf\");\n// after\ntray.add_menu_item(\"reload_config\");","handlingStrategy":"validation","validationCode":"const VALID_IDS: &[&str] = &[\"show_config_folder\",\"reload_config\",\"toggle_window_animations\",\"run_on_startup\",\"exit\"];\nfn is_valid_tray_id(id: &str) -> bool { VALID_IDS.contains(&id) }","typeGuard":"fn parse_tray_event(id: &str) -> Option<SystemTrayEvent> { SystemTrayEvent::from_str(id).ok() }","tryCatchPattern":"let event = match SystemTrayEvent::from_str(id) {\n  Ok(e) => e,\n  Err(_) => { tracing::warn!(\"Unknown tray event: {}\", id); return; }\n};","preventionTips":["Use the enum's IDs (not hand-written strings) when registering menu items.","Keep menu registration and `from_str` arms in sync when adding items.","Restart the tray after upgrading so IDs from old builds don't replay."],"tags":["rust","system-tray","parsing"],"backgroundTag":"invalid-enum-value","analyzedSha":"5709ad0a3c7c386bbc3e38166a865ffc12937515","analyzedAt":"2026-09-08T03:26:40.288Z","contentChangedAt":"2026-09-08T03:26:40.288Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}