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

VAD processing cancelled

Error message

VAD processing cancelled

What it means

This is not a failure: the file-scope VAD pass aborted because the progress callback returned false at a >=5% progress checkpoint. The caller deliberately cancels - typically the UI cancelling a retranscription or VAD job on a large audio file.

Source

Thrown at frontend/src-tauri/src/audio/vad.rs:390

            // Warn if chunk processing took too long (>1 second)
            if elapsed.as_secs() > 1 {
                warn!("VAD: Chunk {} took {:?} - possible performance issue", chunk_count, elapsed);
            }

            all_segments.extend(segments);

            processed += chunk.len();
            let progress = ((processed * 100) / total_samples) as u32;

            // Call progress callback every 5%
            if progress >= last_progress + 5 {
                debug!("VAD: Progress {}% ({} segments found so far)", progress, all_segments.len());

                // Check for cancellation
                if !progress_callback(progress, all_segments.len()) {
                    info!("VAD: Cancelled by callback at {}%", progress);
                    return Err(anyhow!("VAD processing cancelled"));
                }

                last_progress = progress;
            }
        }

        let final_segments = processor.flush()?;
        all_segments.extend(final_segments);

        info!("VAD: Complete! Found {} speech segments", all_segments.len());
    } else {
        // Small file - process all at once
        all_segments = processor.process_audio(samples_mono_16k)?;
        let final_segments = processor.flush()?;
        all_segments.extend(final_segments);
    }

    Ok(all_segments)

View on GitHub (pinned to 0281737d87)

Solutions

  1. Handle it as a distinct 'cancelled' outcome in the UI, not an error toast
  2. Use a dedicated error variant (e.g. VadError::Cancelled) instead of an anyhow string so callers can match on it
  3. Return the partial segments found so far if partial results are useful

Example fix

// before
if !progress_callback(progress, all_segments.len()) {
    return Err(anyhow!("VAD processing cancelled"));
}

// after - a dedicated variant so callers distinguish cancellation from real errors
#[derive(thiserror::Error, Debug)]
enum VadError {
    #[error("cancelled by caller at {progress}%")]
    Cancelled { progress: u32 },
    #[error(transparent)]
    Other(#[from] anyhow::Error),
}

if !progress_callback(progress, all_segments.len()) {
    return Err(VadError::Cancelled { progress }.into());
}
Defensive patterns

Strategy: try-catch

Try / catch

// Distinguish cancellation from real failures
match detect_speech_segments_with_progress(data, cb).await {
    Ok(segs) => { /* done */ }
    Err(e) if e.to_string().contains("cancelled") => {
        info!("VAD cancelled by user"); // show 'Cancelled' in UI, not an error
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A progress_callback closure returns false (user pressed Cancel in the retranscription UI) once progress advances by at least 5%, triggering the early return with this message.

Common situations: User cancels retranscription of a large recording; the frontend tears down a view and its callback returns false to stop background work.

Related errors


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