cjpais/Handy · error · anyhow::Error
Model not found: {}
Error message
Model not found: {} What it means
download_model looked up model_id in the available_models map (catalog entries plus discovered/custom models) and found nothing. The id string is the single source of truth on both sides, so this is an id mismatch, not a download problem.
Source
Thrown at src-tauri/src/managers/model.rs:2160
HttpDownloadOutcome::Completed => {
fs::rename(&partial_path, &model_path)?;
info!(
"Mirror download of {} completed and verified ({:?})",
model_id, model_path
);
Ok(true)
}
}
}
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 existsView on GitHub (pinned to 98a4d80cce)
Solutions
- Re-fetch the model list (available models command) and use the exact id it returns
- Check for trailing/leading whitespace or case differences in the id
- If the list was modified concurrently, refresh the UI state before retrying
Example fix
// before
manager.download_model(model_id).await?;
// after
if manager.get_model_info(model_id).is_none() {
anyhow::bail!("unknown model id {model_id}; refresh the model list");
}
manager.download_model(model_id).await?; Defensive patterns
Strategy: validation
Validate before calling
if manager.get_model_info(model_id).is_none() {
anyhow::bail!("unknown model id {model_id} — refresh the available models list");
}
manager.download_model(model_id).await?; Try / catch
manager.download_model(model_id).await
.with_context(|| format!("download failed for id {model_id}; does it exist in the current model list?"))? Prevention
- Pass ids straight from the model-list response — never hand-build them
- Refresh the list after rescan/delete events before issuing downloads
- Trim and case-normalize ids at the boundary
When it happens
Trigger: UI list is stale (model removed by rescan or another window while a download request was queued); id typo; invoking with an id from a different app version or hand-written integration code.
Common situations: Race between a catalog rescan and a queued download; scripts/CLI driving the command layer with hardcoded ids after an update renamed entries; state desync between frontend model list and backend map.
Related errors
- No download source for model
- Model not available: {}
- threshold must be between 0.0 and 1.0
- Failed to create VAD: {e}
- Failed to create SileroVad: {}
AI-assisted analysis of cjpais/Handy@98a4d80cce (2026-08-16).
Data as JSON: /api/errors/8c481dd4618201b3.
Report an issue: GitHub.