cjpais/Handy · critical · anyhow::Error

Failed to resolve VAD path

Error message

Failed to resolve VAD path: {}

What it means

Tauri's path resolver failed while resolving resources/models/silero_vad_v4.onnx against BaseDirectory::Resource — the resource base directory itself could not be determined or the resolution errored. This is distinct from 'file missing': the resolver fails before any filesystem check, typically because the resources directory is absent or mislocated in the installed bundle (resource bundling config or install layout problem).

Solutions

  1. Ensure src-tauri/resources/models/silero_vad_v4.onnx exists and tauri.conf.json bundle.resources includes it, then rebuild the bundle
  2. Inspect the installed app's Resources directory and confirm models/silero_vad_v4.onnx is present next to the binary
  3. If shipping a custom layout, keep the resource dir in the location Tauri derives for your bundle target
  4. Add a startup diagnostic that logs the resolved resource base dir to catch packaging drift early
Defensive patterns

Strategy: validation

Validate before calling

// resolve once at startup and verify the target file, so packaging drift is caught immediately
let vad_path = app.path()
    .resolve("resources/models/silero_vad_v4.onnx", tauri::path::BaseDirectory::Resource)
    .with_context(|| "resource dir unresolved — check bundle.resources in tauri.conf.json")?;
if !vad_path.exists() {
    anyhow::bail!("bundled VAD model missing at {vad_path:?}");
}

Try / catch

if let Err(e) = manager.preload_vad() {
    if e.to_string().contains("Failed to resolve VAD path") {
        // packaging/install issue, not a runtime one: log the app's resource dir,
        // prompt reinstall — do not retry, it cannot succeed with this bundle
    }
    return Err(e);
}

Prevention

When it happens

Trigger: App packaged without the resources dir (bundle.resources missing the models entry in tauri.conf.json); running the binary from an unexpected location so the resource dir cannot be derived; a broken installer/archive layout where Resources/ sits next to the wrong binary; dev-server run where the resource dir path resolves against a stale build.

Common situations: Packaging config drift after moving the resource; distributing a manually-assembled zip that omits Resources/; Linux tarball installs with altered directory structure; NSIS/DMG variants packaging differently than tested.

Related errors


AI-assisted analysis of cjpais/Handy@c89b7bf389 (2026-08-17). Data as JSON: /api/errors/0a8fb545b8cd4b47. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/managers/audio.rs:604

            mute_guard.did_mute = false;
            debug!(
                "Mute removed (restored prev_muted={:?})",
                mute_guard.prev_muted
            );
        }
    }

    pub fn preload_vad(&self) -> Result<(), anyhow::Error> {
        let mut recorder_opt = self.recorder.lock().unwrap();
        if recorder_opt.is_none() {
            let vad_path = self
                .app_handle
                .path()
                .resolve(
                    "resources/models/silero_vad_v4.onnx",
                    tauri::path::BaseDirectory::Resource,
                )
                .map_err(|e| anyhow::anyhow!("Failed to resolve VAD path: {}", e))?;
            let settings = get_settings(&self.app_handle);
            *recorder_opt = Some(create_audio_recorder(
                &vad_path,
                &self.app_handle,
                settings.selected_channel,
                Arc::clone(&self.stream_router),
            )?);
        }
        Ok(())
    }

    pub fn start_microphone_stream(&self) -> Result<(), anyhow::Error> {
        let mut open_flag = self.is_open.lock().unwrap();
        if *open_flag {
            // `is_open` only records that we opened a stream at some point, not
            // that one is still running. If capture has since failed (mic
            // unplugged mid-session, USB dropout), rebuild it before the next
            // recording instead of handing the caller a stalled recorder.

View on GitHub (pinned to c89b7bf389)