{"record":{"id":"b44ffb32813c0631","repo":"tonhowtf/omniget","slug":"spawn-blocking-failed-b44ffb","errorCode":null,"errorMessage":"Spawn blocking failed: {}","messagePattern":"Spawn blocking failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/dependencies.rs","lineNumber":609,"sourceCode":"            let mut entry = archive\n                .by_index(i)\n                .map_err(|e| anyhow!(\"Failed to read zip entry: {}\", e))?;\n\n            let name = entry.name().to_string();\n            for target in &targets {\n                if name.ends_with(target) {\n                    let dest = bin_dir.join(format!(\"{}.new\", target));\n                    let mut out = std::fs::File::create(&dest)?;\n                    std::io::copy(&mut entry, &mut out)?;\n                    break;\n                }\n            }\n        }\n\n        Ok::<(), anyhow::Error>(())\n    })\n    .await\n    .map_err(|e| anyhow!(\"Spawn blocking failed: {}\", e))??;\n\n    Ok(())\n}\n\nasync fn extract_tar_xz_ffmpeg(\n    archive_path: &std::path::Path,\n    bin_dir: &std::path::Path,\n    ffmpeg_name: &str,\n    ffprobe_name: &str,\n) -> anyhow::Result<()> {\n    let archive_path = archive_path.to_path_buf();\n    let bin_dir = bin_dir.to_path_buf();\n    let ffmpeg_name = ffmpeg_name.to_string();\n    let ffprobe_name = ffprobe_name.to_string();\n\n    tokio::task::spawn_blocking(move || {\n        let file = std::fs::File::open(&archive_path)\n            .map_err(|e| anyhow!(\"Failed to open archive: {}\", e))?;","sourceCodeStart":591,"sourceCodeEnd":627,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/dependencies.rs#L591-L627","documentation":"extract_zip_ffmpeg runs its blocking zip-extraction work with tokio::task::spawn_blocking. If the JoinHandle awaits to an Err (task panicked or the runtime was shut down), the error is wrapped as 'Spawn blocking failed' and propagated. The double '??' then re-raises the inner anyhow::Error if the closure itself failed.","triggerScenarios":"The extraction closure panics (e.g. File::create unwrap-style failure inside, index panic, unzip path traversal panic) while the async runtime is active; tokio runtime shutdown during await; blocking pool starvation causing cancellation.","commonSituations":"A panic in File::create/copy due to permission-denied or disk-full inside the closure; app shutting down while ffmpeg install runs; running under a current-thread runtime that drops the blocking task.","solutions":["Check logs for the inner panic backtrace and fix the root cause (permissions, disk space)","Ensure File::create/copy errors inside the closure are mapped to anyhow::Error instead of panicking","Do not drop/terminate the tokio runtime while spawn_blocking is pending","Re-run the operation after resolving the environment issue"],"exampleFix":"// before\nlet mut out = std::fs::File::create(&dest)?; // panics nowhere but propagates as Err -> JoinError only on panic\n// after\nlet mut out = std::fs::File::create(&dest)\n    .map_err(|e| anyhow!(\"Failed to create {}: {}\", dest.display(), e))?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match tokio::task::spawn_blocking(move || extract()).await {\n    Ok(Ok(())) => {},\n    Ok(Err(e)) => return Err(e),\n    Err(join_err) => {\n        eprintln!(\"extraction task panicked: {join_err}\");\n        // retry once in a fresh blocking task after fixing env\n    }\n}","preventionTips":["Never panic inside spawn_blocking closures; map all std::fs/io results to anyhow::Error","Hold the tokio runtime until all blocking tasks finish (don't abort mid-install)","Check disk space and write permissions before spawning the extraction task","Avoid running installs during application shutdown"],"tags":["tokio","spawn-blocking","panic"],"backgroundTag":"thread-interrupted","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}