{"record":{"id":"927dae38a4ddea49","repo":"cjpais/Handy","slug":"failed-to-create-copy-last-transcript-item","errorCode":null,"errorMessage":"failed to create copy last transcript item","messagePattern":"failed to create copy last transcript item","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/tray.rs","lineNumber":238,"sourceCode":"}\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    };\n\n    // Record intent and claim a sequence number in one critical section, so\n    // sequence order == the order in which state changes were requested.\n    let (seq, icon_state) = {\n        let mut inner = state.lock();\n        update(&mut inner);\n        inner.next_seq += 1;\n        (inner.next_seq, inner.icon_state)","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/cjpais/Handy/blob/fbd4e15fa14a721c66c57006ae110428b9e255b3/src-tauri/src/tray.rs#L220-L256","documentation":"Panic when MenuItem::with_id fails to create the 'copy_last_transcript' item. Same muda failure family as the other tray items: the menu subsystem cannot allocate the item — duplicated id, invalid id/label, or the tray being rebuilt while the app handle is tearing down. Immediately after this line, menu assembly also queries TranscriptionManager state, but that is unrelated to the creation failure.","triggerScenarios":"Tray menu build where MenuItem::with_id(app, \"copy_last_transcript\", strings.copy_last_transcript, true, None) errors — id collision or rebuild racing shutdown.","commonSituations":"Frequent tray refreshes (theme changes, Secure Input toggling on/off forcing menu rebuilds) overlapping quit; forks renaming/duplicating the item id.","solutions":["Keep 'copy_last_transcript' unique within the menu build","Coalesce tray rebuilds triggered in quick succession and cancel pending rebuilds at shutdown","Degrade gracefully: log and omit the item — copy-last-transcript is also reachable from history"],"exampleFix":"// before\nlet copy_last_transcript_i = MenuItem::with_id(\n    app,\n    \"copy_last_transcript\",\n    &strings.copy_last_transcript,\n    true,\n    None::<&str>,\n)\n.expect(\"failed to create copy last transcript item\");\n\n// after — non-fatal creation, menu omits the item on failure\nlet copy_last_transcript_i =\n    match MenuItem::with_id(app, \"copy_last_transcript\", &strings.copy_last_transcript, true, None::<&str>) {\n        Ok(item) => Some(item),\n        Err(e) => {\n            log::warn!(\"copy-last-transcript item omitted: {e}\");\n            None\n        }\n    };","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let copy_last_transcript_i =\n    match MenuItem::with_id(app, \"copy_last_transcript\", &strings.copy_last_transcript, true, None::<&str>) {\n        Ok(item) => Some(item),\n        Err(e) => {\n            log::warn!(\"copy-last-transcript tray item skipped: {e}\");\n            None\n        }\n    };","preventionTips":["Treat transcript-access tray items as skippable since history offers the same function","Debounce tray rebuilds triggered by theme changes or Secure Input toggling","Log item id and error on creation failure to make field reports actionable"],"tags":["rust","tauri","tray","muda","menu","transcript"],"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"}