tonhowtf/omniget · error · anyhow::Error
Spawn blocking failed
Error message
Spawn blocking failed: {} What it means
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.
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
Example fix
// before
let mut out = std::fs::File::create(&dest)?; // panics nowhere but propagates as Err -> JoinError only on panic
// after
let mut out = std::fs::File::create(&dest)
.map_err(|e| anyhow!("Failed to create {}: {}", dest.display(), e))?; Defensive patterns
Strategy: try-catch
Try / catch
match tokio::task::spawn_blocking(move || extract()).await {
Ok(Ok(())) => {},
Ok(Err(e)) => return Err(e),
Err(join_err) => {
eprintln!("extraction task panicked: {join_err}");
// retry once in a fresh blocking task after fixing env
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- tarefa de remoção de fundo falhou
- Spawn blocking failed
- spawn_blocking failed
- Writer task panicked
- worker task panicked
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/b44ffb32813c0631.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/dependencies.rs:609
let mut entry = archive
.by_index(i)
.map_err(|e| anyhow!("Failed to read zip entry: {}", e))?;
let name = entry.name().to_string();
for target in &targets {
if name.ends_with(target) {
let dest = bin_dir.join(format!("{}.new", target));
let mut out = std::fs::File::create(&dest)?;
std::io::copy(&mut entry, &mut out)?;
break;
}
}
}
Ok::<(), anyhow::Error>(())
})
.await
.map_err(|e| anyhow!("Spawn blocking failed: {}", e))??;
Ok(())
}
async fn extract_tar_xz_ffmpeg(
archive_path: &std::path::Path,
bin_dir: &std::path::Path,
ffmpeg_name: &str,
ffprobe_name: &str,
) -> anyhow::Result<()> {
let archive_path = archive_path.to_path_buf();
let bin_dir = bin_dir.to_path_buf();
let ffmpeg_name = ffmpeg_name.to_string();
let ffprobe_name = ffprobe_name.to_string();
tokio::task::spawn_blocking(move || {
let file = std::fs::File::open(&archive_path)
.map_err(|e| anyhow!("Failed to open archive: {}", e))?;View on GitHub (pinned to 8600b91f42)