{"record":{"id":"b1666d81696b65c7","repo":"Zackriya-Solutions/meetily","slug":"download-already-in-progress","errorCode":null,"errorMessage":"Download already in progress","messagePattern":"Download already in progress","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src-tauri/src/summary/summary_engine/model_manager.rs","lineNumber":363,"sourceCode":"                Box::new(move |p: DownloadProgress| cb(p.percent)) as Box<dyn Fn(DownloadProgress) + Send>\n            });\n        self.download_model_detailed(model_name, detailed_callback).await\n    }\n\n    /// Download a model with detailed progress (MB, speed, etc.)\n    pub async fn download_model_detailed(\n        &self,\n        model_name: &str,\n        progress_callback: Option<Box<dyn Fn(DownloadProgress) + Send>>,\n    ) -> Result<()> {\n        log::info!(\"Starting download for model: {}\", model_name);\n\n        // Check if already downloading\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\"));\n            }\n        }\n\n        // Get model definition\n        let model_def = get_model_by_name(model_name)\n            .ok_or_else(|| anyhow!(\"Unknown model: {}\", model_name))?;\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 cancellation flag\n        {\n            let mut cancel_flag = self.cancel_download_flag.write().await;\n            *cancel_flag = None;\n        }","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/summary/summary_engine/model_manager.rs#L345-L381","documentation":"download_model_detailed checks the active_downloads set and rejects a second concurrent download of the same model. This is a deliberate guard, not a failure: the first download keeps streaming and keeps emitting progress callbacks.","triggerScenarios":"Double-invoking download for the same model name before the first completes: double-clicked Download button, two components (settings and onboarding) starting the download, or a retry timer firing while the original attempt is still active.","commonSituations":"Frontend not disabling the button after the first invoke; a re-render spawning a duplicate Tauri command call; stall-detection logic that re-invokes on slow progress.","solutions":["Treat this as benign: ignore it and subscribe to the existing download's progress events","Disable the download button while the model reports a downloading status","On the caller side, check model status from list-models before invoking download"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Caller-side guard: only start when not already downloading\nlet models = manager.list_models().await;\nif models.iter().any(|m| m.name == name && m.is_downloading()) {\n    return Ok(()); // existing download already reports progress\n}","typeGuard":null,"tryCatchPattern":"match manager.download_model_detailed(name, cb).await {\n    Err(e) if e.to_string() == \"Download already in progress\" => Ok(()), // benign: first download continues\n    other => other,\n}","preventionTips":["Disable the download button as soon as the command is invoked","Drive button state from the model's downloading status, not from local flags","Have only one component own download initiation (settings page)"],"tags":["concurrency","download","guard","rust"],"backgroundTag":"operation-already-in-progress","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}