{"record":{"id":"8269324a75937630","repo":"Zackriya-Solutions/meetily","slug":"cannot-pause-when-not-recording","errorCode":null,"errorMessage":"Cannot pause when not recording","messagePattern":"Cannot pause when not recording","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/audio/recording_state.rs","lineNumber":179,"sourceCode":"    pub fn stop_recording(&self) {\n        self.is_recording.store(false, Ordering::SeqCst);\n        self.is_paused.store(false, Ordering::SeqCst);\n        // 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        }","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/audio/recording_state.rs#L161-L197","documentation":"RecordingState::pause_recording refuses the call because the is_recording AtomicBool is false - there is no active session to pause. The state machine only permits pause from the recording-and-not-paused state, so pausing a stopped or never-started recording is rejected.","triggerScenarios":"Frontend sends pause_recording after the session already stopped (Stop clicked first, or an auto-stop fired on a fatal pipeline/device error); stale UI still shows a Pause button; double-fire where a stop handler runs before the pause handler.","commonSituations":"User clicks Stop and Pause almost simultaneously; UI missed the recording-stopped event; automation scripts issuing fixed pause/resume sequences regardless of state.","solutions":["Derive pause/resume button enablement from backend recording-state events or the is_recording command","In the command layer, treat 'not recording' pause as a benign no-op with a log line rather than surfacing an error","Check is_recording before invoking pause from scripts or tests"],"exampleFix":"// before\nstate.pause_recording()?;\n\n// after - tolerate benign ordering races instead of failing the command\nif !state.is_recording() {\n    log::warn!(\"Pause ignored - recording already stopped\");\n    return Ok(());\n}\nstate.pause_recording()?;","handlingStrategy":"validation","validationCode":"// Frontend: gate the Pause action on live backend state\nif (await invoke<boolean>('is_recording')) {\n  await invoke('pause_recording');\n}","typeGuard":null,"tryCatchPattern":"Match the returned error string; on 'Cannot pause when not recording' treat as a benign no-op (log, update UI to stopped state) instead of showing a failure.","preventionTips":["Enable/disable Pause and Resume buttons from backend recording-state events","Handle recording-stopped events to clear paused indicators","Make command handlers idempotent where the state race is benign"],"tags":["state-machine","recording","invalid-transition","pause-resume"],"backgroundTag":"invalid-state-transition","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}