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 models

View on GitHub (pinned to 0281737d87)

Solutions

  1. Wait for the in-flight download — subscribe to its progress events until 100 or completion
  2. Disable the Download button while the model shows Downloading status
  3. 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

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


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/93f8d7903733853b. Report an issue: GitHub.