aaif-goose/goose · warning

Download already in progress

Error message

Download already in progress

What it means

download_model_sharded refuses to start when an entry for model_id already has status Downloading, rejecting duplicate concurrent starts for the same model rather than deduplicating them. The companion reserve_download path exists so callers can do this check-and-insert atomically.

Source

Thrown at crates/goose-download-manager/src/lib.rs:229

    pub async fn download_model_sharded_with_bearer_token(
        &self,
        model_id: String,
        files: Vec<(String, PathBuf)>,
        total_size_hint: u64,
        bearer_token: Option<String>,
        on_complete: Option<Box<dyn FnOnce() + Send + 'static>>,
    ) -> Result<()> {
        info!(model_id = %model_id, file_count = files.len(), "Starting model download");
        {
            let mut downloads = self
                .downloads
                .lock()
                .map_err(|_| anyhow::anyhow!("Failed to acquire lock"))?;

            if let Some(existing) = downloads.get(&model_id) {
                if existing.status == DownloadStatus::Downloading {
                    anyhow::bail!("Download already in progress");
                }
                if existing.status == DownloadStatus::Cancelled && !existing.task_exited {
                    anyhow::bail!(
                        "Download is being cancelled; wait for it to finish before restarting"
                    );
                }
            }

            downloads.insert(
                model_id.clone(),
                DownloadProgress {
                    model_id: model_id.clone(),
                    status: DownloadStatus::Downloading,
                    bytes_downloaded: 0,
                    total_bytes: total_size_hint,
                    progress_percent: 0.0,
                    speed_bps: None,
                    eta_seconds: None,

View on GitHub (pinned to 3810898a74)

Solutions

  1. Poll progress (get_progress / list_progress) and wait for the existing download instead of starting again
  2. Cancel the running download first if a restart is intended, then wait for task_exited
  3. Guard call sites so only one start per model_id is in flight

Example fix

// before
manager.download_model_sharded(model_id.clone(), files, size, token, None).await?;
// after
if manager.is_downloading(&model_id) {
    // already running: poll list_progress() until it finishes
    return Ok(());
}
manager.download_model_sharded(model_id.clone(), files, size, token, None).await?;
Defensive patterns

Strategy: validation

Validate before calling

if manager.is_downloading(&model_id) {
    // a download is already running; poll instead of starting a duplicate
    poll_until_finished(&manager, &model_id).await;
} else {
    manager.download_model_sharded(model_id.clone(), files, size, token, None).await?;
}

Try / catch

if let Err(e) = manager.download_model_sharded(id, files, size, token, None).await {
    if e.to_string() == "Download already in progress" {
        poll_until_finished(&manager, &id).await;
        return Ok(());
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Two concurrent download_model calls with the same model_id — double-triggered UI actions, retries that fire before the first attempt exits, parallel automation starting the same model.

Common situations: Front-ends firing start twice on double-click; retry logic that treats a slow start as failed and restarts immediately.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/5110cabe5ef36a2b. Report an issue: GitHub.