cjpais/Handy · error
failed to create version item
Error message
failed to create version item
What it means
Panic when MenuItem::with_id fails to create the disabled 'version' information item for the tray menu. muda item creation is fallible; for this item (no accelerator, disabled) failure means the menu subsystem could not allocate the item — duplicated id, or tray rebuild racing app teardown so the app handle cannot service the request.
Solutions
- Keep 'version' unique within each menu build and centralize tray ids in one module
- Debounce or skip tray rebuilds once shutdown has started
- Convert expect to logged degradation (build the menu without the version line) if the item is non-essential
Example fix
// before
let version_i = MenuItem::with_id(app, "version", &version_label, false, None::<&str>)
.expect("failed to create version item");
// after — include ids in diagnostics when tray creation fails
let version_i = MenuItem::with_id(app, "version", &version_label, false, None::<&str>)
.unwrap_or_else(|e| panic!("failed to create version item (id='version'): {e}")); Defensive patterns
Strategy: fallback
Try / catch
let version_i = match MenuItem::with_id(app, "version", &version_label, false, None::<&str>) {
Ok(item) => Some(item),
Err(e) => {
log::warn!("version tray item skipped: {e}");
None
}
}; Prevention
- Keep tray ids unique per menu build and define them in one place
- Cancel pending tray rebuilds at shutdown
- Degrade to a menu without informational items rather than aborting
When it happens
Trigger: Tray creation/refresh where MenuItem::with_id(app, "version", version_label, false, None) errors — id collision within the same menu, or rebuild during shutdown.
Common situations: Theme-change tray rebuilds racing quit; forks reusing the 'version' id for another item; running on a system where the tray/status-item host is going away mid-build.
Related errors
- failed to create check updates item
- failed to create copy last transcript item
- failed to create settings item
- failed to create cancel item
- failed to create menu
AI-assisted analysis of cjpais/Handy@fbd4e15fa1 (2026-08-17).
Data as JSON: /api/errors/8cd45bb1bec188dc.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/tray.rs:214
// Linux never sets the warning flag (Secure Input is macOS-only),
// but fall back to the normal icon just in case.
AppTheme::Colored => "resources/handy.png",
};
}
match (theme, state) {
// Dark theme uses light icons
(AppTheme::Dark, TrayIconState::Idle) => "resources/tray_idle.png",
(AppTheme::Dark, TrayIconState::Recording) => "resources/tray_recording.png",
(AppTheme::Dark, TrayIconState::Transcribing) => "resources/tray_transcribing.png",
// Light theme uses dark icons
(AppTheme::Light, TrayIconState::Idle) => "resources/tray_idle_dark.png",
(AppTheme::Light, TrayIconState::Recording) => "resources/tray_recording_dark.png",
(AppTheme::Light, TrayIconState::Transcribing) => "resources/tray_transcribing_dark.png",
// Colored theme uses pink icons (for Linux)
(AppTheme::Colored, TrayIconState::Idle) => "resources/handy.png",
(AppTheme::Colored, TrayIconState::Recording) => "resources/recording.png",
(AppTheme::Colored, TrayIconState::Transcribing) => "resources/transcribing.png",
}
}
/// Sets the recording state shown by the tray (icon + Cancel/model menu).
pub fn set_tray_state(app: &AppHandle, state: TrayIconState) {
sync_tray_with(app, |inner| inner.icon_state = state);
}
/// Re-syncs the tray after something other than the recording state changed
/// (theme, Secure Input warning). The recording state itself is preserved.
pub fn refresh_tray_icon(app: &AppHandle) {
sync_tray(app);
}
/// Re-syncs the tray after something the menu depends on changed (model
/// list/selection/loaded state, language, settings).
pub fn update_tray_menu(app: &AppHandle) {
sync_tray(app);
}View on GitHub (pinned to fbd4e15fa1)