{"record":{"id":"601ac44cd569c1b9","repo":"cjpais/Handy","slug":"failed-to-create-vad-e","errorCode":null,"errorMessage":"Failed to create VAD: {e}","messagePattern":"Failed to create VAD: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"src-tauri/src/audio_toolkit/vad/silero.rs","lineNumber":26,"sourceCode":"\nconst SILERO_FRAME_MS: u32 = 30;\nconst SILERO_FRAME_SAMPLES: usize =\n    (constants::WHISPER_SAMPLE_RATE * SILERO_FRAME_MS / 1000) as usize;\n\npub struct SileroVad {\n    engine: Vad,\n    threshold: f32,\n}\n\nimpl SileroVad {\n    pub fn new<P: AsRef<Path>>(model_path: P, threshold: f32) -> Result<Self> {\n        if !(0.0..=1.0).contains(&threshold) {\n            anyhow::bail!(\"threshold must be between 0.0 and 1.0\");\n        }\n\n        Ok(Self {\n            engine: Vad::new(&model_path, constants::WHISPER_SAMPLE_RATE as usize)\n                .map_err(|e| anyhow::anyhow!(\"Failed to create VAD: {e}\"))?,\n            threshold,\n        })\n    }\n}\n\nimpl VoiceActivityDetector for SileroVad {\n    fn push_frame<'a>(&'a mut self, frame: &'a [f32]) -> Result<VadFrame<'a>> {\n        if frame.len() != SILERO_FRAME_SAMPLES {\n            anyhow::bail!(\n                \"expected {SILERO_FRAME_SAMPLES} samples, got {}\",\n                frame.len()\n            );\n        }\n\n        let result = self\n            .engine\n            .compute(frame)\n            .map_err(|e| anyhow::anyhow!(\"Silero VAD error: {e}\"))?;","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/cjpais/Handy/blob/c6fa60da2f13a5af660fba17f37af548855119c5/src-tauri/src/audio_toolkit/vad/silero.rs#L8-L44","documentation":"Wraps a failure of vad_rs::Vad::new() to load the Silero VAD ONNX model from the given path at 16 kHz (constants::WHISPER_SAMPLE_RATE). It fails when the model file does not exist, is not valid ONNX, or the ONNX runtime cannot create a session for it. The threshold is validated before this call, so this error is purely about the model file itself.","triggerScenarios":"Constructing SileroVad::new(model_path, threshold) when silero_vad_v4.onnx is missing from src-tauri/resources/models/ (dev setup step not run), the file is truncated/corrupt (partial copy), or the path points at a non-ONNX file.","commonSituations":"Fresh clone without running the 'curl -o src-tauri/resources/models/silero_vad_v4.onnx' setup command; CI builds where resources are not fetched; antivirus/quarantine modifying the .onnx file; bundling the app without including the resource.","solutions":["Download the Silero model as documented: mkdir -p src-tauri/resources/models && curl -o src-tauri/resources/models/silero_vad_v4.onnx https://blob.handy.computer/silero_vad_v4.onnx","Verify the file is a complete ONNX binary (size > 1 MB, not an HTML error page from a failed curl).","Confirm the path passed to SileroVad::new resolves at runtime (resource dir in dev vs. bundled prod) and that tauri.conf.json includes it as a resource.","Re-download if the file is corrupt; a bad ONNX will fail deterministically."],"exampleFix":"// before\nlet vad = SileroVad::new(model_path, threshold)?;\n\n// after — fail with an actionable message before hitting the ONNX loader\nif !model_path.as_ref().exists() {\n    anyhow::bail!(\n        \"Silero VAD model missing at {} — run the documented setup download\",\n        model_path.as_ref().display()\n    );\n}\nlet vad = SileroVad::new(model_path, threshold)?;","handlingStrategy":"validation","validationCode":"// Before constructing the VAD, assert the model is present and non-trivial\nlet p = resource_dir.join(\"models/silero_vad_v4.onnx\");\nlet meta = std::fs::metadata(&p)?;\nif meta.len() < 1_000_000 {\n    anyhow::bail!(\"Silero model at {} looks truncated ({} bytes)\", p.display(), meta.len());\n}\nlet vad = SileroVad::new(&p, threshold)?;","typeGuard":null,"tryCatchPattern":"match SileroVad::new(&path, threshold) {\n    Ok(v) => v,\n    Err(e) => {\n        error!(\"VAD init failed ({e}); run the setup download before starting the app\");\n        std::process::exit(1); // startup-critical resource missing\n    }\n}","preventionTips":["Fetch the Silero ONNX in the build/CI script so a fresh clone always has it.","Add the model to tauri.conf.json resources so production bundles ship it.","Fail fast at startup with a clear message instead of first-use.","Sanity-check file size (>1 MB) to catch HTML error pages saved as .onnx."],"tags":["vad","silero","onnx","model-file","startup"],"backgroundTag":"model-file-load-failed","analyzedSha":"c6fa60da2f13a5af660fba17f37af548855119c5","analyzedAt":"2026-08-17T10:29:55.597Z","contentChangedAt":"2026-08-17T10:29:55.597Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}