{"record":{"id":"957065f7430eff79","repo":"libnyanpasu/clash-nyanpasu","slug":"failed-to-start-download-e","errorCode":null,"errorMessage":"failed to start download: {e}","messagePattern":"failed to start download: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/core/download/mod.rs","lineNumber":128,"sourceCode":"            .adapter(adapter)\n            .save_path(save_path)\n            .threaded_runtime(ThreadedRuntimeImpl::new_tokio_rt())\n            .cancel_token(inner.cancel.clone())\n            .on_task_state_changed(move |event| cb_inner.on_event(event))\n            .build()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"failed to build download task: {e}\"))?;\n        Ok(Self {\n            inner,\n            task: Mutex::new(task),\n        })\n    }\n\n    pub async fn start(&self) -> anyhow::Result<()> {\n        let mut task = self.task.lock().await;\n        task.run()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"failed to start download: {e}\"))?;\n        match task.wait().await {\n            Ok(()) => Ok(()),\n            Err(e) => {\n                *self.inner.state.write() = DownloaderState::Failed(e.to_string());\n                Err(anyhow::anyhow!(\"download failed: {e}\"))\n            }\n        }\n    }\n\n    pub fn status(&self) -> DownloadStatus {\n        let prog = *self.inner.progress.read();\n        DownloadStatus {\n            state: self.inner.state.read().clone(),\n            downloaded: prog.downloaded,\n            total: prog.total,\n            speed: prog.speed,\n        }\n    }","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/core/download/mod.rs#L110-L146","documentation":"Wraps a failure of the download task's `run()` call in `DownloadSession::start`. `run()` initiates the transfer; if the underlying downloader cannot even begin (runtime submit failure, task already finished/cancelled, adapter setup error), the error is re-wrapped as \"failed to start download: {e}\". This is distinct from a mid-transfer failure, which surfaces later as \"download failed\".","triggerScenarios":"Calling `DownloadSession::start()` and the task's `run()` future returns an error — e.g. starting a task that was already run/completed, the cancel token already fired, or the threaded runtime rejects the spawn.","commonSituations":"Calling `start()` twice on the same session; calling start after `cancel()`; resource-exhaustion in the runtime; bug in session reuse after a previous terminal state.","solutions":["Create a fresh `DownloadSession` for each download instead of re-running a finished/failed one.","Do not call `start()` after `cancel()` or after `status()` reports a terminal state; check status first.","Read the wrapped `{e}` to identify the underlying cause (already-run, cancelled, runtime failure).","If transient (runtime spawn failure), retry after freeing resources."],"exampleFix":"// before\nsession.start().await?;\n// after\nif let DownloadSession::Failed(_) = session.status().state {\n    anyhow::bail!(\"previous download failed; create a new session\");\n}\nsession.start().await.map_err(|e| anyhow!(\"cannot start download: {e:#}\"))?;","handlingStrategy":"validation","validationCode":"// check session state before starting\nif let DownloaderState::Failed(_) | DownloaderState::Finished = *session.status().state {\n    anyhow::bail!(\"session already terminal; create a new DownloadSession\");\n}","typeGuard":null,"tryCatchPattern":"session.start().await\n    .map_err(|e| { log::error!(\"download could not start: {e:#}\"); e })?;","preventionTips":["Use one DownloadSession per download; never call start() twice on the same session","Do not start after cancel(); check status() first","Ensure the tokio runtime is alive and not saturated","Treat a start failure as a session-lifecycle bug, not a network issue"],"tags":["rust","download","task","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}