cjpais/Handy · error

Failed to create VAD: {e}

Error message

Failed to create VAD: {e}

What it means

Wraps Vad::new from the vad-rs crate, which creates an ONNX Runtime inference session for the Silero VAD model at the given path at 16 kHz (constants::WHISPER_SAMPLE_RATE). It fails when the model file is missing or unreadable, is not a valid ONNX file, or the ONNX Runtime backend cannot start (missing/incompatible native libraries).

Source

Thrown at src-tauri/src/audio_toolkit/vad/silero.rs:26

const SILERO_FRAME_MS: u32 = 30;
const SILERO_FRAME_SAMPLES: usize =
    (constants::WHISPER_SAMPLE_RATE * SILERO_FRAME_MS / 1000) as usize;

pub struct SileroVad {
    engine: Vad,
    threshold: f32,
}

impl SileroVad {
    pub fn new<P: AsRef<Path>>(model_path: P, threshold: f32) -> Result<Self> {
        if !(0.0..=1.0).contains(&threshold) {
            anyhow::bail!("threshold must be between 0.0 and 1.0");
        }

        Ok(Self {
            engine: Vad::new(&model_path, constants::WHISPER_SAMPLE_RATE as usize)
                .map_err(|e| anyhow::anyhow!("Failed to create VAD: {e}"))?,
            threshold,
        })
    }
}

impl VoiceActivityDetector for SileroVad {
    fn push_frame<'a>(&'a mut self, frame: &'a [f32]) -> Result<VadFrame<'a>> {
        if frame.len() != SILERO_FRAME_SAMPLES {
            anyhow::bail!(
                "expected {SILERO_FRAME_SAMPLES} samples, got {}",
                frame.len()
            );
        }

        let result = self
            .engine
            .compute(frame)
            .map_err(|e| anyhow::anyhow!("Silero VAD error: {e}"))?;

View on GitHub (pinned to 98a4d80cce)

Solutions

  1. Verify the model file exists and is non-trivial (ls -l src-tauri/resources/models/silero_vad_v4.onnx)
  2. Re-download it: curl -o src-tauri/resources/models/silero_vad_v4.onnx https://blob.handy.computer/silero_vad_v4.onnx
  3. Confirm the resource is bundled (resources entry in tauri.conf.json) so resolve() finds it in packaged builds
  4. If the file is fine, check the ONNX Runtime native libs (ldd / otool -L on the onnxruntime artifact)

Example fix

// before
let silero = SileroVad::new(vad_path, threshold)?; // opaque failure

// after — fail with an actionable message before touching ONNX
let meta = std::fs::metadata(&vad_path)
    .map_err(|e| anyhow::anyhow!("VAD model missing at {vad_path:?}: {e}"))?;
if meta.len() < 1024 {
    anyhow::bail!("VAD model at {vad_path:?} looks truncated ({} bytes)", meta.len());
}
let silero = SileroVad::new(&vad_path, threshold)?;
Defensive patterns

Strategy: validation

Validate before calling

// cheap pre-flight before creating the engine
let meta = std::fs::metadata(&vad_path)
    .map_err(|e| anyhow::anyhow!("VAD model not found at {vad_path:?}: {e}"))?;
if meta.len() < 1_000 {
    anyhow::bail!("VAD model at {vad_path:?} is only {} bytes — re-download it", meta.len());
}

Try / catch

let silero = match SileroVad::new(&vad_path, threshold) {
    Ok(v) => v,
    Err(e) => {
        // {e} already wraps the inner Vad::new cause; surface it with the path
        anyhow::bail!("cannot start VAD from {vad_path:?}: {e:#}");
    }
};

Prevention

When it happens

Trigger: resources/models/silero_vad_v4.onnx absent because the dev setup step (curl per AGENTS.md/BUILD.md) was skipped; the file is truncated or corrupt; the resolved path points at the wrong location; the onnxruntime dynamic library fails to load (glibc/ABI mismatch on Linux, missing dylib on macOS).

Common situations: Fresh clone without downloading the VAD model; resource not listed in the bundle so production builds lack the file; OS/toolchain upgrade breaking the onnxruntime native lib; file copied with wrong permissions.

Related errors


AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16). Data as JSON: /api/errors/601ac44cd569c1b9. Report an issue: GitHub.