cjpais/Handy · warning · anyhow::Error

No download source for model

Error message

No download source for model

What it means

download_model matched ModelSource::Local for the requested model. Local models are files the user imported or that were discovered on disk — they have no URL and no Hugging Face repo, so there is nothing to download by design.

Source

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

    pub async fn download_model(&self, model_id: &str) -> Result<()> {
        let model_info = {
            let models = self.available_models.lock().unwrap();
            models.get(model_id).cloned()
        };

        let model_info =
            model_info.ok_or_else(|| anyhow::anyhow!("Model not found: {}", model_id))?;

        let (url, expected_sha256) = match &model_info.source {
            ModelSource::Url { url, sha256 } => (url.clone(), sha256.clone()),
            ModelSource::HuggingFace { repo_id, revision } => {
                return self
                    .download_hf_model(&model_info, repo_id.clone(), revision.clone())
                    .await;
            }
            ModelSource::Local => {
                return Err(anyhow::anyhow!("No download source for model"));
            }
        };
        let model_path = self.models_dir.join(&model_info.filename);
        let partial_path = self
            .models_dir
            .join(format!("{}.partial", &model_info.filename));

        // Don't download if complete version already exists
        if model_path.exists() {
            // Clean up any partial file that might exist
            if partial_path.exists() {
                let _ = fs::remove_file(&partial_path);
            }
            self.update_download_status()?;
            return Ok(());
        }

        // Mark as downloading

View on GitHub (pinned to 98a4d80cce)

Solutions

  1. Guard the UI/action: hide or disable download for ModelSource::Local / is_custom entries
  2. For local models, point the user to the model's own source to obtain the file manually

Example fix

// before
manager.download_model(&model.id).await?; // fires for local models

// after
if matches!(model.source, ModelSource::Local) {
    return Ok(()); // nothing to download — skip instead of erroring
}
manager.download_model(&model.id).await?;
Defensive patterns

Strategy: validation

Validate before calling

match manager.get_model_info(model_id) {
    Some(info) if matches!(info.source, ModelSource::Local) => {
        // nothing to download — skip rather than error
        return Ok(());
    }
    Some(_) => { /* safe to download */ }
    None => anyhow::bail!("unknown model id {model_id}"),
}

Prevention

When it happens

Trigger: Calling download_model on a custom/imported or discovered-local model (is_custom or ModelSource::Local in the catalog); a UI that enables the download action for local entries.

Common situations: Frontend showing a generic download button for every list row; integrations assuming all models are downloadable; custom models created via 'add local model' flows.

Related errors


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