cjpais/Handy · error
Failed to create SileroVad: {}
Error message
Failed to create SileroVad: {} What it means
Thin wrapper in create_audio_recorder (audio.rs:272) around SileroVad::new. The message carries the inner cause via {e}, so it fires for exactly two reasons: the threshold range check (errors[0]) or ONNX session creation (errors[1]). In this codebase the threshold is the fixed VAD_THRESHOLD constant, so real occurrences are almost always the ONNX/VAD engine failing to load the Silero model.
Source
Thrown at src-tauri/src/managers/audio.rs:272
#[derive(Debug, Default, Clone, Copy)]
struct MuteState {
did_mute: bool,
prev_muted: Option<bool>,
}
/* ──────────────────────────────────────────────────────────────── */
fn create_audio_recorder(
vad_path: &Path,
app_handle: &tauri::AppHandle,
selected_channel: Option<u16>,
stream_router: Arc<StreamRouter>,
) -> Result<AudioRecorder, anyhow::Error> {
// A single Silero engine covers both the offline and streaming policies (never
// active at once within a recording), so the recorder reconfigures its
// hangover tail per session rather than keeping two ONNX sessions resident.
let silero = SileroVad::new(vad_path, VAD_THRESHOLD)
.map_err(|e| anyhow::anyhow!("Failed to create SileroVad: {}", e))?;
let smoothed_vad = SmoothedVad::new(
Box::new(silero),
VAD_PREFILL_FRAMES,
VAD_OFFLINE_HANGOVER_FRAMES,
VAD_ONSET_FRAMES,
);
// Recorder with VAD, a spectrum-level callback that forwards level updates to
// the frontend, and an audio-frame callback that feeds live streaming via a
// shared `StreamRouter` (captured directly, not via Tauri state — see its docs).
let recorder = AudioRecorder::new()
.map_err(|e| anyhow::anyhow!("Failed to create AudioRecorder: {}", e))?
.with_vad(
Box::new(smoothed_vad),
VAD_OFFLINE_HANGOVER_FRAMES,
VAD_STREAMING_HANGOVER_FRAMES,
)
.with_selected_channel(selected_channel)View on GitHub (pinned to 98a4d80cce)
Solutions
- Read the appended {e} to see which inner failure it is (threshold vs 'Failed to create VAD')
- If it is the inner VAD failure, verify/re-download silero_vad_v4.onnx (see error[1])
- If VAD_THRESHOLD was modified, confirm it is within 0.0..=1.0
- For packaged builds, confirm the model ships inside the bundle resources
Defensive patterns
Strategy: try-catch
Try / catch
let recorder = create_audio_recorder(&vad_path, &app, channel, router)
.context("failed to build audio recorder"); // {e} chains the inner SileroVad cause Prevention
- Treat this as a pass-through: always read the chained cause, fix the inner error
- Call preload_vad() eagerly at startup so a broken VAD model fails fast with one clear message
When it happens
Trigger: preload_vad() resolving resources/models/silero_vad_v4.onnx to a path where the file is missing or corrupt; ONNX Runtime unable to initialize in the packaged app because the model was not bundled.
Common situations: Same as the underlying Vad::new failure: skipped dev setup step, unbundled resource, broken onnxruntime libs. Only appears at recording setup time (first recording or preload), so the app starts fine and fails later.
Related errors
- threshold must be between 0.0 and 1.0
- Failed to create VAD: {e}
- Failed to create AudioRecorder: {}
- Failed to resolve VAD path: {}
- Failed to open recorder: {}
AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16).
Data as JSON: /api/errors/9cc9d7f9d9c9a446.
Report an issue: GitHub.