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
- Verify the model file exists and is non-trivial (ls -l src-tauri/resources/models/silero_vad_v4.onnx)
- Re-download it: curl -o src-tauri/resources/models/silero_vad_v4.onnx https://blob.handy.computer/silero_vad_v4.onnx
- Confirm the resource is bundled (resources entry in tauri.conf.json) so resolve() finds it in packaged builds
- 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
- Download silero_vad_v4.onnx as part of the dev setup script, not manually
- Assert the resource exists during app setup (preload_vad) so failure surfaces at startup, not mid-recording
- Verify bundle resources include the model before shipping release builds
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
- threshold must be between 0.0 and 1.0
- Failed to create SileroVad: {}
- Failed to load moonshine model {}: {}
- Failed to load moonshine streaming model {}: {}
- Failed to load SenseVoice model {}: {}
AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16).
Data as JSON: /api/errors/601ac44cd569c1b9.
Report an issue: GitHub.