libnyanpasu/clash-nyanpasu · error

failed to build download task: {e}

Error message

failed to build download task: {e}

What it means

Wraps a failure from the download library's `Task::builder()...build().await` in `DownloadSession::new`. The builder assembles a download task around an adapter (reqwest-based here), a save path and a threaded runtime; if the underlying task cannot be constructed (bad save path, runtime/thread setup failure, adapter error), the error is re-wrapped with this message, so the original cause is embedded in `{e}`.

Source

Thrown at backend/tauri/src/core/download/mod.rs:117

        url: Url,
        save_path: PathBuf,
    ) -> anyhow::Result<Self> {
        let inner = Arc::new(SessionInner {
            state: RwLock::new(DownloaderState::Idle),
            progress: RwLock::new(ProgressSnapshot::default()),
            cancel: CancellationToken::new(),
        });
        let adapter: AnyAdapter = Box::new(NyanpasuReqwestAdapter::new(client, url));
        let cb_inner = inner.clone();
        let task = Task::builder()
            .adapter(adapter)
            .save_path(save_path)
            .threaded_runtime(ThreadedRuntimeImpl::new_tokio_rt())
            .cancel_token(inner.cancel.clone())
            .on_task_state_changed(move |event| cb_inner.on_event(event))
            .build()
            .await
            .map_err(|e| anyhow::anyhow!("failed to build download task: {e}"))?;
        Ok(Self {
            inner,
            task: Mutex::new(task),
        })
    }

    pub async fn start(&self) -> anyhow::Result<()> {
        let mut task = self.task.lock().await;
        task.run()
            .await
            .map_err(|e| anyhow::anyhow!("failed to start download: {e}"))?;
        match task.wait().await {
            Ok(()) => Ok(()),
            Err(e) => {
                *self.inner.state.write() = DownloaderState::Failed(e.to_string());
                Err(anyhow::anyhow!("download failed: {e}"))
            }
        }

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Read the wrapped `{e}` cause; ensure `save_path` exists (create it with `std::fs::create_dir_all`) and is writable.
  2. Check disk space and permissions on the target directory.
  3. Validate the URL before constructing the session (scheme, host).
  4. Retry if the failure was a transient runtime-spawn/resource error.

Example fix

// before
let session = DownloadSession::new(client, url, save_path.clone()).await?;
// after
std::fs::create_dir_all(&save_path)?;
let session = DownloadSession::new(client, url, save_path).await
    .map_err(|e| { log::error!("download task build failed: {e:#}"); e })?;
Defensive patterns

Strategy: try-catch

Validate before calling

std::fs::create_dir_all(&save_path)
    .map_err(|e| anyhow!("save path {} unusable: {e}", save_path.display()))?;
if url.scheme() != "http" && url.scheme() != "https" {
    anyhow::bail!("unsupported URL scheme: {}", url.scheme());
}

Try / catch

let session = DownloadSession::new(client, url, save_path).await
    .with_context(|| format!("building download task for {}", save_path.display()))?;

Prevention

When it happens

Trigger: Constructing `DownloadSession::new(client, url, save_path)` where the download-task builder fails: `save_path` is unwritable/does not exist or cannot be created, the threaded tokio runtime cannot be spawned, or the adapter/task configuration is rejected by the download crate.

Common situations: Downloading to a directory that does not exist or lacks write permission (e.g. protected install dir, read-only mount, full disk); invalid URL scheme rejected at task build; environment where spawning the threaded runtime fails (resource limits).

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/7d593094f6d10fbe. Report an issue: GitHub.