aaif-goose/goose · info
Download cancelled
Error message
Download cancelled
What it means
Cancellation checkpoint inside cancellable_sleep, the helper that waits out retry backoff. Every <=500ms it re-checks the shared progress map; if cancel_download() set status = Cancelled, it bails with 'Download cancelled', aborting the backoff and the whole download task. The spawn error handler stores the message in DownloadProgress.error but keeps the status Cancelled (it only overwrites status when it is not already Cancelled) and sets task_exited = true.
Source
Thrown at crates/goose-download-manager/src/lib.rs:326
});
Ok(())
}
const MAX_RETRIES: u32 = 10;
const RETRY_BASE_DELAY: std::time::Duration = std::time::Duration::from_secs(2);
const RETRY_MAX_DELAY: std::time::Duration = std::time::Duration::from_secs(60);
async fn cancellable_sleep(
delay: std::time::Duration,
downloads: &DownloadMap,
model_id: &str,
) -> Result<(), anyhow::Error> {
let check_interval = std::time::Duration::from_millis(500);
let start = std::time::Instant::now();
while start.elapsed() < delay {
if Self::is_cancelled(downloads, model_id) {
anyhow::bail!("Download cancelled");
}
let remaining = delay.saturating_sub(start.elapsed());
tokio::time::sleep(std::cmp::min(check_interval, remaining)).await;
}
Ok(())
}
fn is_cancelled(downloads: &DownloadMap, model_id: &str) -> bool {
if let Ok(downloads) = downloads.lock() {
if let Some(progress) = downloads.get(model_id) {
return progress.status == DownloadStatus::Cancelled;
}
}
false
}
#[allow(clippy::too_many_arguments)]
/// Download multiple files sequentially, tracking cumulative progress under one model_id.View on GitHub (pinned to 3810898a74)
Solutions
- Nothing to fix if the cancel was intentional: treat status Cancelled as the source of truth, not this error string
- Restart the download once task_exited is true; already-completed shards are skipped on restart
- If cancels are unexpected, find the caller invoking cancel_download (UI event, timeout watchdog)
Defensive patterns
Strategy: validation
Validate before calling
// cancellation is a status, not an exception: read the progress map
let user_cancelled = manager.get_progress(model_id)
.is_some_and(|p| p.status == DownloadStatus::Cancelled); Try / catch
if let Err(e) = download_result {
if e.to_string() == "Download cancelled" {
// expected termination after cancel_download(); show Cancelled state, not an error
} else {
// real failure: e is also mirrored in DownloadProgress.error
}
} Prevention
- Decide success/failure from DownloadProgress.status, with error as detail only
- Only call cancel_download when you truly want the transfer stopped
- After cancelling, keep the model entry around until task_exited is true
When it happens
Trigger: cancel_download() is called while the task is sleeping between retry attempts, i.e. after a connection error or transient HTTP (5xx/408/429) failure put it into exponential backoff (2s doubling, capped 60s).
Common situations: User cancels a download that is already struggling with a flaky network, so the task happens to be in a retry sleep; automated jobs aborting during an HF/CDN outage.
Related errors
- Download is being cancelled; wait for it to finish before re
- Download failed after {} retries: {}
- Download failed after {} retries due to stream interruption
- Failed to create directory: {}
- Failed to download: HTTP {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/f3ecd3c6dac6e6db.
Report an issue: GitHub.