cjpais/Handy · error · anyhow::Error
Silero VAD error: {e}
Error message
Silero VAD error: {e} What it means
Wraps an error from the Silero ONNX inference call (engine.compute(frame)) during per-frame voice activity detection. The frame length is validated first, so this error means the ONNX session itself failed to execute — typically a corrupted model, a runtime/provider failure, or the LSTM state getting into a bad state after an I/O or session error. It surfaces mid-recording, one 512-sample frame at a time.
Source
Thrown at src-tauri/src/audio_toolkit/vad/silero.rs:44
.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}"))?;
if result.prob > self.threshold {
Ok(VadFrame::Speech(frame))
} else {
Ok(VadFrame::Noise)
}
}
fn frame_samples(&self) -> usize {
SILERO_FRAME_SAMPLES
}
fn reset(&mut self) {
// Clear the Silero LSTM hidden/cell state so a new session doesn't
// inherit recurrent context from the previous recording.
self.engine.reset();
}
}View on GitHub (pinned to c6fa60da2f)
Solutions
- Re-download silero_vad_v4.onnx and restart the app — a compute failure almost always traces to a damaged model file.
- If it recurs, pin/reinstall the onnxruntime version used by the vad-rs dependency (check Cargo.lock for version drift).
- Check system memory and disk health; ONNX execution allocates arenas that can fail under pressure.
- Call reset() on the VAD between recording sessions (the code does this) to avoid carrying bad recurrent state forward.
Example fix
// before
let frame = vad.push_frame(samples)?;
// after — treat a VAD compute failure as session-poisoned: reset once, then surface
match vad.push_frame(samples) {
Ok(frame) => frame,
Err(e) => {
warn!("VAD compute failed ({e}); resetting session state");
vad.reset();
return Err(e);
}
} Defensive patterns
Strategy: try-catch
Try / catch
let frame = match vad.push_frame(chunk) {
Ok(f) => f,
Err(e) => {
// session may be poisoned: reset state, drop this recording
vad.reset();
return Err(anyhow::anyhow!("VAD compute failed; session reset: {e}"));
}
}; Prevention
- Call reset() between recording sessions so bad recurrent state never carries over.
- Keep the .onnx model file read-only after download to prevent accidental corruption.
- Log the frame index when compute fails — repeated failures at frame 0 point to a corrupt model.
- Verify the model hash once at startup rather than discovering corruption mid-recording.
When it happens
Trigger: Calling SileroVad::push_frame() when the ONNX runtime session errors during compute: model file corrupted on disk, ONNX runtime version/provider mismatch, or engine state invalidated after a previous partial failure.
Common situations: Disk corruption or a truncated silero_vad_v4.onnx that loaded but fails on inference; an ONNX runtime upgraded to an incompatible version; the model resource swapped/modified while the app is running; rare provider-level failures under memory pressure.
Related errors
- Failed to create SileroVad: {}
- Failed to create VAD: {e}
- Parakeet transcription failed: {}
- Moonshine transcription failed: {}
- Moonshine streaming transcription failed: {}
AI-assisted analysis of cjpais/Handy@c6fa60da2f (2026-08-17).
Data as JSON: /api/errors/419854a3dca8d677.
Report an issue: GitHub.