Zackriya-Solutions/meetily · warning · anyhow::Error
Download already in progress for model: {}
Error message
Download already in progress for model: {} What it means
download_model checks the active_downloads set at entry and rejects a second concurrent download of the same model name. This prevents two HTTP streams writing the same ggml-<name>.bin path simultaneously. The first download continues unaffected; the duplicate call fails immediately.
Source
Thrown at frontend/src-tauri/src/whisper_engine/whisper_engine.rs:905
}
Ok(format!("Successfully deleted model '{}'", model_name))
}
_ => {
Err(anyhow!("Can only delete corrupted or available models. Model '{}' has status: {:?}", model_name, model_info.status))
}
}
}
pub async fn download_model(&self, model_name: &str, progress_callback: Option<Box<dyn Fn(u8) + Send>>) -> Result<()> {
log::info!("Starting download for model: {}", model_name);
// Check if download is already in progress for this model
{
let active = self.active_downloads.read().await;
if active.contains(model_name) {
log::warn!("Download already in progress for model: {}", model_name);
return Err(anyhow!("Download already in progress for model: {}", model_name));
}
}
// Add to active downloads
{
let mut active = self.active_downloads.write().await;
active.insert(model_name.to_string());
}
// Clear any previous cancellation flag for this model
{
let mut cancel_flag = self.cancel_download_flag.write().await;
*cancel_flag = None;
}
// Official ggerganov/whisper.cpp model URLs from Hugging Face
let model_url = match model_name {
// Standard f16 modelsView on GitHub (pinned to 0281737d87)
Solutions
- Wait for the in-flight download — subscribe to its progress events until 100 or completion
- Disable the Download button while the model shows Downloading status
- If the flag is stale because a prior call hung, cancel the download or restart the app, then retry
Example fix
// before
button.onClick(() => invoke('download_model', { modelName })); // double-fire
// after
let downloading = false;
button.onClick(async () => {
if (downloading) return;
downloading = true;
try { await invoke('download_model', { modelName }); }
finally { downloading = false; }
}); Defensive patterns
Strategy: validation
Validate before calling
const models = await invoke<ModelInfo[]>('get_whisper_models');
const downloading = models.find(x => x.name === modelName)?.status === 'Downloading';
if (downloading) {
// attach to the existing progress stream instead of starting a second one
return;
}
await invoke('download_model', { modelName }); Type guard
const isDownloading = (m: ModelInfo | undefined): boolean => m?.status === 'Downloading';
Try / catch
try {
await invoke('download_model', { modelName });
} catch (e) {
if (String(e).includes('already in progress')) {
// benign: join the existing download's progress events
} else { throw e; }
} Prevention
- Debounce/disable the Download button from the first click until a terminal status arrives
- Drive all download entry points (manual + auto) through one coordinator that checks active status
- Treat 'already in progress' as info, not error, in telemetry
When it happens
Trigger: Double-clicking the Download button before it disables; two UI components both invoking download_model for the same name; automatic retry logic firing while the first attempt still streams.
Common situations: Missing debounce on the download button; background auto-download racing a user-initiated download; optimistic-refresh frontend that re-issues the call.
Related errors
- Model {} is currently downloading
- Whisper engine not initialized
- Download already in progress for model: {}
- Download already in progress
- Model {} has error: {}
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/93f8d7903733853b.
Report an issue: GitHub.