{"record":{"id":"d231cd09be5e7c70","repo":"Zackriya-Solutions/meetily","slug":"recording-is-already-paused","errorCode":null,"errorMessage":"Recording is already paused","messagePattern":"Recording is already paused","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/audio/recording_state.rs","lineNumber":182,"sourceCode":"        // Clear pause tracking when stopping\n        *self.pause_start.lock().unwrap() = None;\n        // CRITICAL: Clear audio sender to close the pipeline channel\n        // This ensures the pipeline loop exits properly after processing all chunks\n        *self.audio_sender.lock().unwrap() = None;\n        // CRITICAL: Clear device references to release microphone/speaker\n        // Without this, Arc<AudioDevice> references persist and keep the mic active\n        *self.microphone_device.lock().unwrap() = None;\n        *self.system_device.lock().unwrap() = None;\n        *self.disconnected_device.lock().unwrap() = None;\n        log::info!(\"Recording stopped, device references cleared\");\n    }\n\n    pub fn pause_recording(&self) -> Result<()> {\n        if !self.is_recording() {\n            return Err(anyhow::anyhow!(\"Cannot pause when not recording\"));\n        }\n        if self.is_paused() {\n            return Err(anyhow::anyhow!(\"Recording is already paused\"));\n        }\n\n        self.is_paused.store(true, Ordering::SeqCst);\n        *self.pause_start.lock().unwrap() = Some(Instant::now());\n        log::info!(\"Recording paused\");\n        Ok(())\n    }\n\n    pub fn resume_recording(&self) -> Result<()> {\n        if !self.is_recording() {\n            return Err(anyhow::anyhow!(\"Cannot resume when not recording\"));\n        }\n        if !self.is_paused() {\n            return Err(anyhow::anyhow!(\"Recording is not paused\"));\n        }\n\n        // Calculate pause duration and add to total\n        if let Some(pause_start) = self.pause_start.lock().unwrap().take() {","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/audio/recording_state.rs#L164-L200","documentation":"pause_recording was called while is_paused is already true - a double-pause. The guard makes repeated pause fail rather than silently restarting the pause timer, which would otherwise corrupt total_pause_duration accounting.","triggerScenarios":"Double-click on the Pause button; a keyboard shortcut and a UI button both firing; retry of a pause command that already succeeded but whose result was not observed.","commonSituations":"Missing debounce on UI buttons; event replay in tests; race between an automatic pause (device reconnect) and a user pause.","solutions":["Make the caller idempotent: treat 'already paused' as success","Debounce or disable the Pause button once the paused state is confirmed","Check is_recording_paused before sending the command"],"exampleFix":"// before\nstate.pause_recording()?;\n\n// after - idempotent pause at the call site\nmatch state.pause_recording() {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"already paused\") => { /* desired state reached */ }\n    Err(e) => return Err(e),\n}","handlingStrategy":"validation","validationCode":"// Frontend: only pause when actually unpaused\nif ((await invoke<boolean>('is_recording')) && !(await invoke<boolean>('is_recording_paused'))) {\n  await invoke('pause_recording');\n}","typeGuard":null,"tryCatchPattern":"Treat 'Recording is already paused' as success (the desired state is already reached); only surface other errors.","preventionTips":["Debounce the pause/resume toggle button","Use a single toggle control driven by is_recording_paused rather than separate buttons","Do not retry a pause that already returned success"],"tags":["state-machine","recording","invalid-transition","idempotency"],"backgroundTag":"invalid-state-transition","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}