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

  1. Read the appended {e} to see which inner failure it is (threshold vs 'Failed to create VAD')
  2. If it is the inner VAD failure, verify/re-download silero_vad_v4.onnx (see error[1])
  3. If VAD_THRESHOLD was modified, confirm it is within 0.0..=1.0
  4. 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

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


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