cjpais/Handy · warning · anyhow::Error

Model is currently downloading

Error message

Model is currently downloading: {}

What it means

get_model_path refuses to return a path while is_downloading is true — a deliberate guard so the transcription pipeline never consumes a partially written file or extracting directory. The flag is set for the whole download/extract lifecycle, so this fires when a model is used mid-download rather than after a failed one.

Solutions

  1. Wait for the model-download-complete event before using the model
  2. Disable the model selector / recording UI while any download is active
  3. If the download appears hung, cancel it (cancel_download resets the flag) and retry or pick an already-downloaded model
Defensive patterns

Strategy: validation

Validate before calling

// check in-flight state before resolving the path
let info = manager.get_model_info(model_id).expect("validated earlier");
if info.is_downloading {
    anyhow::bail!("Model {model_id} is still downloading — wait for model-download-complete");
}

Try / catch

match manager.get_model_path(id) {
    Err(e) if e.to_string().contains("currently downloading") => {
        // wait or cancel: cancel_download resets the flag if the transfer is wedged
    }
    other => other,
}

Prevention

When it happens

Trigger: User starts a recording or switches the active model while a download is in flight; queued transcription resolving the path during extraction; download stuck (see [3]) so the flag stays true for minutes.

Common situations: Impatient first-run usage during initial model download; switching from a small to a large model and immediately recording; a stalled download leaving the model in downloading state.

Related errors


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

Appendix: source

Thrown at src-tauri/src/managers/model.rs:2573

        }
        // Keep the persisted preference here: an already-loaded engine may
        // still be usable, and re-downloading this model should restore it.
        // Startup and explicit Rescan perform the broader selection cleanup.
        let _ = self.app_handle.emit("models-updated", ());
    }

    pub fn get_model_path(&self, model_id: &str) -> Result<PathBuf> {
        let model_info = self
            .get_model_info(model_id)
            .ok_or_else(|| anyhow::anyhow!("Model not found: {}", model_id))?;

        if !model_info.is_downloaded {
            return Err(anyhow::anyhow!("Model not available: {}", model_id));
        }

        // Ensure we don't return partial files/directories
        if model_info.is_downloading {
            return Err(anyhow::anyhow!(
                "Model is currently downloading: {}",
                model_id
            ));
        }

        if let ModelSource::HuggingFace { repo_id, revision } = &model_info.source {
            if let Some(path) = hf_cached_path(repo_id, revision, &model_info.filename) {
                return Ok(path);
            }
            // Mirror-fallback download or manual drop-in in the models dir.
            // The complete file only ever appears after verification, so a
            // stale `.partial` alongside it is leftover noise, not a veto —
            // clear it rather than declaring the model missing.
            let local_path = self.models_dir.join(&model_info.filename);
            if local_path.exists() {
                let partial_path = self
                    .models_dir
                    .join(format!("{}.partial", &model_info.filename));

View on GitHub (pinned to ba10ce1943)