tonhowtf/omniget · error
spawn_blocking failed
Error message
spawn_blocking failed: {} What it means
copy_file_macos runs osascript inside tokio::task::spawn_blocking. If the blocking task itself panics or the runtime is shutting down, the JoinError is wrapped in this 'spawn_blocking failed: {}' error before the osascript result is even examined.
Solutions
- Retry the copy once the runtime is stable; transient shutdown races resolve after init completes.
- Ensure copy_file_to_clipboard is awaited within a live tokio runtime (not after runtime shutdown).
- Inspect the wrapped JoinError message for a panic; fix the panicking code in the closure.
Example fix
// before tokio::runtime::Runtime::new()?.block_on(copy_file_to_clipboard(...)); // dropped too early // after let rt = tokio::runtime::Runtime::new()?; rt.block_on(copy_file_to_clipboard(...)); // keep rt alive for the call
Defensive patterns
Strategy: try-catch
Try / catch
match copy_file_to_clipboard(path).await {
Err(e) if e.to_string().starts_with("spawn_blocking failed") => {
tracing::warn!("runtime race during clipboard copy: {e}");
// retry once with a live runtime
}
other => other?,
} Prevention
- Only call clipboard APIs inside a live tokio runtime
- Avoid spawning clipboard copies during app shutdown
- Fix panics inside the blocking closure — they surface as this error
When it happens
Trigger: Calling copy_file_to_clipboard on macOS when the spawned blocking task panics (e.g. poisoned state) or the tokio runtime is being dropped during shutdown.
Common situations: App teardown racing a clipboard copy; a panic inside the closure; calling clipboard code from a non-async context where the runtime is already gone.
Related errors
- Send cancelled while paused
- osascript failed
- spawn_blocking failed
- spawn_blocking failed
- Spawn blocking failed
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/48f2fbc3f7df2b8b.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/clipboard.rs:45
#[cfg(target_os = "windows")]
{
copy_file_windows(&path_str).await
}
}
#[cfg(target_os = "macos")]
async fn copy_file_macos(path: &str) -> anyhow::Result<()> {
let path = path.to_string();
let output = tokio::task::spawn_blocking(move || {
crate::core::process::std_command("osascript")
.args([
"-e",
&format!("set the clipboard to POSIX file \"{}\"", path),
])
.output()
})
.await
.map_err(|e| anyhow::anyhow!("spawn_blocking failed: {}", e))??;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(anyhow::anyhow!("osascript failed: {}", stderr));
}
tracing::info!("[clipboard] copied file to clipboard (macOS)");
Ok(())
}
#[cfg(target_os = "linux")]
async fn copy_file_linux(path: &str) -> anyhow::Result<()> {
let uri = format!("file://{}", path);
let uri_clone = uri.clone();
let xclip_result = tokio::task::spawn_blocking(move || {
let mut child = match crate::core::process::std_command("xclip")
.args(["-selection", "clipboard", "-target", "text/uri-list"])View on GitHub (pinned to 8600b91f42)