{"record":{"id":"2e0932be393f3b12","repo":"cjpais/Handy","slug":"failed-to-create-check-updates-item","errorCode":null,"errorMessage":"failed to create check updates item","messagePattern":"failed to create check updates item","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/tray.rs","lineNumber":230,"sourceCode":"        (AppTheme::Colored, TrayIconState::Recording) => \"resources/recording.png\",\n        (AppTheme::Colored, TrayIconState::Transcribing) => \"resources/transcribing.png\",\n    }\n}\n\n/// Sets the recording state shown by the tray (icon + Cancel/model menu).\npub fn set_tray_state(app: &AppHandle, state: TrayIconState) {\n    sync_tray_with(app, |inner| inner.icon_state = state);\n}\n\n/// Re-syncs the tray after something other than the recording state changed\n/// (theme, Secure Input warning). The recording state itself is preserved.\npub fn refresh_tray_icon(app: &AppHandle) {\n    sync_tray(app);\n}\n\n/// Re-syncs the tray after something the menu depends on changed (model\n/// list/selection/loaded state, language, settings).\npub fn update_tray_menu(app: &AppHandle) {\n    sync_tray(app);\n}\n\n/// Records the current desired tray state and schedules one apply on the main\n/// thread (or lets an already-pending apply pick it up). Never blocks on the\n/// main thread.\n///\n/// The snapshot (settings, model list, loaded state) is computed on the\n/// *calling* thread on purpose: the main-thread applier must not take manager\n/// locks that a worker may hold across slow work (see #1716).\npub fn sync_tray(app: &AppHandle) {\n    sync_tray_with(app, |_| {});\n}\n\nfn sync_tray_with(app: &AppHandle, update: impl FnOnce(&mut TrayInner)) {\n    let Some(state) = app.try_state::<TrayState>() else {\n        return;\n    };","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/cjpais/Handy/blob/fbd4e15fa14a721c66c57006ae110428b9e255b3/src-tauri/src/tray.rs#L212-L248","documentation":"Panic when MenuItem::with_id fails to create the 'check_updates' item. Its enabled state reflects settings.update_checks_enabled, but that flag does not affect creation; failure causes are the same muda family — duplicated id, invalid label/id, or a tray rebuild racing app teardown. Because strings come from i18n, an unexpected label issue (e.g. interior NUL on some backends) is theoretically possible but not observed.","triggerScenarios":"Tray menu build where MenuItem::with_id(app, \"check_updates\", strings.check_updates, settings.update_checks_enabled, None) errors — id collision or teardown race.","commonSituations":"Theme-change rebuilds racing quit; forks adding a second updates entry with the same id; localized label regressions from the i18n pipeline.","solutions":["Keep 'check_updates' unique within the menu build","Skip tray rebuilds during shutdown","Degrade gracefully (log and build the menu without the item) since update checks also surface in the settings UI"],"exampleFix":"// before\nlet check_updates_i = MenuItem::with_id(\n    app,\n    \"check_updates\",\n    &strings.check_updates,\n    settings.update_checks_enabled,\n    None::<&str>,\n)\n.expect(\"failed to create check updates item\");\n\n// after — include the id and settings state in diagnostics\nlet check_updates_i = MenuItem::with_id(\n    app,\n    \"check_updates\",\n    &strings.check_updates,\n    settings.update_checks_enabled,\n    None::<&str>,\n)\n.unwrap_or_else(|e| panic!(\"failed to create check updates item (id='check_updates'): {e}\"));","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let check_updates_i =\n    match MenuItem::with_id(app, \"check_updates\", &strings.check_updates, settings.update_checks_enabled, None::<&str>) {\n        Ok(item) => Some(item),\n        Err(e) => {\n            log::warn!(\"check-updates tray item skipped: {e}\");\n            None // update checks remain available in the settings UI\n        }\n    };","preventionTips":["Keep tray ids unique and defined centrally","Remember update checks have a settings-UI path, so the tray item is safely skippable","Coalesce frequent tray rebuilds and stop them at shutdown"],"tags":["rust","tauri","tray","muda","menu","updates"],"backgroundTag":"tray-menu-item-creation-failed","analyzedSha":"fbd4e15fa14a721c66c57006ae110428b9e255b3","analyzedAt":"2026-08-17T10:29:55.597Z","contentChangedAt":"2026-08-17T10:29:55.597Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}