cjpais/Handy · error · anyhow::Error
Model not available
Error message
Model not available: {} What it means
The model entry exists but is_downloaded is false, so get_model_path refuses to hand out a path — there is nothing on disk to transcribe with. This is a state/ordering error: the caller asked to use a model before it was downloaded (or after a failed/rolled-back download).
Solutions
- Trigger downloadModel and wait for the model-download-complete event before enabling recording
- Restrict the model selector in settings to entries with is_downloaded true
- If it just completed, refresh model status — the flag updates via update_download_status
Example fix
// before (TS) — start recording regardless of model state
await startRecording();
// after — gate recording on the selected model being ready
const info = await commands.getModelInfo(selectedModelId);
if (info.status === "ok" && !info.data.is_downloaded) {
await commands.downloadModel(selectedModelId);
// wait for the model-download-complete event before proceeding
}
await startRecording(); Defensive patterns
Strategy: validation
Validate before calling
// gate on download state before resolving the path
let info = manager.get_model_info(model_id)
.ok_or_else(|| anyhow::anyhow!("Model not found: {model_id}"))?;
if !info.is_downloaded {
manager.download_model(model_id).await?; // caller waits for model-download-complete
} Try / catch
match manager.get_model_path(id) {
Err(e) if e.to_string().contains("Model not available") => {
// trigger download and surface 'model not ready' to the user — do not transcribe
}
other => other,
} Prevention
- Only allow selecting downloaded models as the active transcription model
- Wait for the model-download-complete event after triggering downloads before enabling recording
When it happens
Trigger: Recording started before the selected model finished downloading; a previous download failed so the flag stayed false; is_downloaded not yet refreshed after completion (event race between model-download-complete and the status map).
Common situations: Onboarding flow letting users record before the first model download completes; model switch to a not-yet-downloaded model; settings restored on a new machine where models dir is empty.
Related errors
- Model not downloaded
- Complete model directory not found
- Failed to extract archive
- Model is currently downloading
- Model is not loaded for transcription.
AI-assisted analysis of cjpais/Handy@ba10ce1943 (2026-08-17).
Data as JSON: /api/errors/420357d55ccb4dfe.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/managers/model.rs:2568
if removed {
info!("Removing vanished discovered model '{}'", model_id);
} else {
info!("Marking model '{}' as unavailable on disk", model_id);
}
// 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.View on GitHub (pinned to ba10ce1943)