{"record":{"id":"93f8d7903733853b","repo":"Zackriya-Solutions/meetily","slug":"download-already-in-progress-for-model-93f8d7","errorCode":null,"errorMessage":"Download already in progress for model: {}","messagePattern":"Download already in progress for model: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/whisper_engine/whisper_engine.rs","lineNumber":905,"sourceCode":"                }\n\n                Ok(format!(\"Successfully deleted model '{}'\", model_name))\n            }\n            _ => {\n                Err(anyhow!(\"Can only delete corrupted or available models. Model '{}' has status: {:?}\", model_name, model_info.status))\n            }\n        }\n    }\n    \n    pub async fn download_model(&self, model_name: &str, progress_callback: Option<Box<dyn Fn(u8) + Send>>) -> Result<()> {\n        log::info!(\"Starting download for model: {}\", model_name);\n\n        // Check if download is already in progress for this model\n        {\n            let active = self.active_downloads.read().await;\n            if active.contains(model_name) {\n                log::warn!(\"Download already in progress for model: {}\", model_name);\n                return Err(anyhow!(\"Download already in progress for model: {}\", model_name));\n            }\n        }\n\n        // Add to active downloads\n        {\n            let mut active = self.active_downloads.write().await;\n            active.insert(model_name.to_string());\n        }\n\n        // Clear any previous cancellation flag for this model\n        {\n            let mut cancel_flag = self.cancel_download_flag.write().await;\n            *cancel_flag = None;\n        }\n\n        // Official ggerganov/whisper.cpp model URLs from Hugging Face\n        let model_url = match model_name {\n            // Standard f16 models","sourceCodeStart":887,"sourceCodeEnd":923,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/whisper_engine/whisper_engine.rs#L887-L923","documentation":"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.","triggerScenarios":"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.","commonSituations":"Missing debounce on the download button; background auto-download racing a user-initiated download; optimistic-refresh frontend that re-issues the call.","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"],"exampleFix":"// before\nbutton.onClick(() => invoke('download_model', { modelName })); // double-fire\n\n// after\nlet downloading = false;\nbutton.onClick(async () => {\n  if (downloading) return;\n  downloading = true;\n  try { await invoke('download_model', { modelName }); }\n  finally { downloading = false; }\n});","handlingStrategy":"validation","validationCode":"const models = await invoke<ModelInfo[]>('get_whisper_models');\nconst downloading = models.find(x => x.name === modelName)?.status === 'Downloading';\nif (downloading) {\n  // attach to the existing progress stream instead of starting a second one\n  return;\n}\nawait invoke('download_model', { modelName });","typeGuard":"const isDownloading = (m: ModelInfo | undefined): boolean => m?.status === 'Downloading';","tryCatchPattern":"try {\n  await invoke('download_model', { modelName });\n} catch (e) {\n  if (String(e).includes('already in progress')) {\n    // benign: join the existing download's progress events\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["whisper","download","concurrency","rust","tauri"],"backgroundTag":"operation-already-in-progress","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}