Zackriya-Solutions/meetily · warning · anyhow::Error

Recording is not paused

Error message

Recording is not paused

What it means

resume_recording was called when is_paused is false - the session is either actively recording or fully stopped-and-not-paused. The guard prevents a spurious resume from corrupting pause-duration accounting (pause_start would be None).

Source

Thrown at frontend/src-tauri/src/audio/recording_state.rs:196

        if !self.is_recording() {
            return Err(anyhow::anyhow!("Cannot pause when not recording"));
        }
        if self.is_paused() {
            return Err(anyhow::anyhow!("Recording is already paused"));
        }

        self.is_paused.store(true, Ordering::SeqCst);
        *self.pause_start.lock().unwrap() = Some(Instant::now());
        log::info!("Recording paused");
        Ok(())
    }

    pub fn resume_recording(&self) -> Result<()> {
        if !self.is_recording() {
            return Err(anyhow::anyhow!("Cannot resume when not recording"));
        }
        if !self.is_paused() {
            return Err(anyhow::anyhow!("Recording is not paused"));
        }

        // Calculate pause duration and add to total
        if let Some(pause_start) = self.pause_start.lock().unwrap().take() {
            let pause_duration = pause_start.elapsed();
            *self.total_pause_duration.lock().unwrap() += pause_duration;
            log::info!("Recording resumed after pause of {:.2}s", pause_duration.as_secs_f64());
        }

        self.is_paused.store(false, Ordering::SeqCst);
        Ok(())
    }

    pub fn is_recording(&self) -> bool {
        self.is_recording.load(Ordering::SeqCst)
    }

    pub fn is_paused(&self) -> bool {

View on GitHub (pinned to 0281737d87)

Solutions

  1. Use one toggle button driven by the canonical paused state (is_recording_paused command)
  2. Treat 'not paused' resume as idempotent success at the caller
  3. Check paused state before sending resume

Example fix

// before
state.resume_recording()?;

// after - idempotent resume at the call site
match state.resume_recording() {
    Ok(()) => {}
    Err(e) if e.to_string().contains("not paused") => { /* desired state reached */ }
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: validation

Validate before calling

// Frontend: only resume when actually paused
if (await invoke<boolean>('is_recording_paused')) {
  await invoke('resume_recording');
}

Try / catch

Treat 'Recording is not paused' as success (target state already active); surface only genuine failures.

Prevention

When it happens

Trigger: Double Resume click; Resume raced with an earlier resume that already succeeded; a single toggle button sending resume when the state already flipped.

Common situations: Rapid toggling of a combined pause/resume button; duplicated event delivery; scripts replaying resume commands.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/87bb2edd853992bb. Report an issue: GitHub.