{"record":{"id":"9cc9d7f9d9c9a446","repo":"cjpais/Handy","slug":"failed-to-create-silerovad","errorCode":null,"errorMessage":"Failed to create SileroVad: {}","messagePattern":"Failed to create SileroVad: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"src-tauri/src/managers/audio.rs","lineNumber":290,"sourceCode":"/// user's regular selected microphone is missing.\nstruct MicrophoneResolution {\n    device: Option<cpal::Device>,\n    unavailable_selected_microphone: Option<String>,\n}\n\n/* ──────────────────────────────────────────────────────────────── */\n\nfn create_audio_recorder(\n    vad_path: &Path,\n    app_handle: &tauri::AppHandle,\n    selected_channel: Option<u16>,\n    stream_router: Arc<StreamRouter>,\n) -> Result<AudioRecorder, anyhow::Error> {\n    // A single Silero engine covers both the offline and streaming policies (never\n    // active at once within a recording), so the recorder reconfigures its\n    // hangover tail per session rather than keeping two ONNX sessions resident.\n    let silero = SileroVad::new(vad_path, VAD_THRESHOLD)\n        .map_err(|e| anyhow::anyhow!(\"Failed to create SileroVad: {}\", e))?;\n    let smoothed_vad = SmoothedVad::new(\n        Box::new(silero),\n        VAD_PREFILL_FRAMES,\n        VAD_OFFLINE_HANGOVER_FRAMES,\n        VAD_ONSET_FRAMES,\n    );\n\n    // Recorder with VAD, a spectrum-level callback that forwards level updates to\n    // the frontend, and an audio-frame callback that feeds live streaming via a\n    // shared `StreamRouter` (captured directly, not via Tauri state — see its docs).\n    let recorder = AudioRecorder::new()\n        .map_err(|e| anyhow::anyhow!(\"Failed to create AudioRecorder: {}\", e))?\n        .with_vad(\n            Box::new(smoothed_vad),\n            VAD_OFFLINE_HANGOVER_FRAMES,\n            VAD_STREAMING_HANGOVER_FRAMES,\n        )\n        .with_selected_channel(selected_channel)","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/cjpais/Handy/blob/c89b7bf38974ad317177389f5bfe28236f0d64e3/src-tauri/src/managers/audio.rs#L272-L308","documentation":"SileroVad::new failed to load or instantiate the ONNX VAD model at resources/models/silero_vad_v4.onnx. Construction spans reading the file and creating an ONNX runtime session, so failures mean: the file is missing (dev checkout that skipped the documented curl step), the file is corrupt/truncated, or the ONNX runtime cannot initialize (missing dynamic libraries or an incompatible ort build). Recording cannot start without VAD, hence the impact.","triggerScenarios":"Fresh clone built without fetching silero_vad_v4.onnx into src-tauri/resources/models (AGENTS.md prerequisite); resource not bundled because tauri.conf.json's bundle.resources omits it; onnx file truncated by an interrupted curl; ort shared libraries missing on the runtime system.","commonSituations":"New contributor/CI environment missing the manually-downloaded resource; packaging config drift dropping the models dir from bundles; binary copied to a machine without the required ONNX runtime libs.","solutions":["Run the documented step: curl -o src-tauri/resources/models/silero_vad_v4.onnx https://blob.handy.computer/silero_vad_v4.onnx","Verify the file size/hash against the upstream blob and re-download if truncated","Check that tauri.conf.json bundle.resources includes resources/models so the file ships","Confirm ONNX runtime dynamic libraries are present/loaded (check the inner error text after 'Failed to create SileroVad:')"],"exampleFix":"// before\nlet silero = SileroVad::new(vad_path, VAD_THRESHOLD)\n    .map_err(|e| anyhow::anyhow!(\"Failed to create SileroVad: {}\", e))?;\n\n// after — distinguish 'missing resource' from 'broken runtime' with an actionable message\nif !vad_path.exists() {\n    anyhow::bail!(\n        \"VAD model missing at {vad_path:?} — fetch silero_vad_v4.onnx (see AGENTS.md prerequisites)\"\n    );\n}\nlet silero = SileroVad::new(vad_path, VAD_THRESHOLD)\n    .map_err(|e| anyhow::anyhow!(\"Failed to create SileroVad: {}\", e))?;","handlingStrategy":"validation","validationCode":"// fail with an actionable message before ONNX runtime involvement\nif !vad_path.exists() {\n    anyhow::bail!(\n        \"VAD model missing at {vad_path:?} — run the AGENTS.md curl step or fix bundling\"\n    );\n}\nlet silero = SileroVad::new(vad_path, VAD_THRESHOLD)?;","typeGuard":null,"tryCatchPattern":"if let Err(e) = create_audio_recorder(&vad_path, ...) {\n    if e.to_string().contains(\"Failed to create SileroVad\") {\n        // resource/packaging problem: check file existence + size before retrying,\n        // and surface a 'reinstall / refetch resource' message to the user\n    }\n    return Err(e);\n}","preventionTips":["Add the silero_vad_v4.onnx fetch to a setup script so fresh clones and CI can't skip it","Assert the resource exists (and its byte size) in a startup self-test, failing fast with a clear message","Verify bundle.resources covers resources/models on every packaging change"],"tags":["rust","vad","onnx","silero","resource","model-load"],"backgroundTag":"onnx-model-load-failed","analyzedSha":"c89b7bf38974ad317177389f5bfe28236f0d64e3","analyzedAt":"2026-08-17T10:29:55.597Z","contentChangedAt":"2026-08-17T10:29:55.597Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}