{"record":{"id":"bbb50f7ff5c2e7d3","repo":"tonhowtf/omniget","slug":"spawn-blocking-failed-ytdlp","errorCode":null,"errorMessage":"spawn_blocking failed: {}","messagePattern":"spawn_blocking failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/ytdlp.rs","lineNumber":1886,"sourceCode":"    // Fail-closed. O yt-dlp publica `SHA2-256SUMS` em toda release; não\n    // conseguir buscá-lo é indistinguível de alguém suprimindo a verificação,\n    // então o binário é descartado em vez de instalado sem conferência.\n    let expected = integrity::expected_from_sums_url(&client, &sums_url, asset)\n        .await\n        .map_err(|e| anyhow!(\"yt-dlp: verificacao de integridade impossivel — {}\", e))?;\n    integrity::verify_sha256(&bytes, &expected, &format!(\"yt-dlp ({:?})\", channel))?;\n\n    let temp = target.with_file_name(format!(\n        \"{}.new\",\n        target\n            .file_name()\n            .and_then(|n| n.to_str())\n            .unwrap_or(\"yt-dlp\")\n    ));\n    let temp_clone = temp.clone();\n    tokio::task::spawn_blocking(move || std::fs::write(&temp_clone, &bytes))\n        .await\n        .map_err(|e| anyhow!(\"spawn_blocking failed: {}\", e))??;\n\n    crate::core::dependencies::replace_managed_binary(&temp, &target)?;\n\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::PermissionsExt;\n        let perms = std::fs::Permissions::from_mode(0o755);\n        std::fs::set_permissions(&target, perms)?;\n    }\n\n    #[cfg(target_os = \"macos\")]\n    {\n        let target_mac = target.clone();\n        let _ = tokio::task::spawn_blocking(move || {\n            crate::core::process::std_command(\"xattr\")\n                .args([\"-d\", \"com.apple.quarantine\"])\n                .arg(&target_mac)\n                .output()","sourceCodeStart":1868,"sourceCodeEnd":1904,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/ytdlp.rs#L1868-L1904","documentation":"The downloaded bytes are written to a temp file inside `tokio::task::spawn_blocking`; if the blocking task itself fails (the JoinError case — task panicked or was cancelled), the error is wrapped as \"spawn_blocking failed: {e}\". Note a plain `std::fs::write` error would surface via the following `??` as an IO error, so this message specifically indicates the blocking task did not complete normally.","triggerScenarios":"The spawned blocking task panics (e.g. unexpected condition in fs::write path handling) or the tokio runtime is shutting down and cancels the task while writing the temp file during a yt-dlp download/install.","commonSituations":"App shutdown/runtime teardown racing a background yt-dlp download; a panic inside the closure; runtime built without the blocking-thread pool or with blocking threads exhausted and tasks cancelled.","solutions":["Retry the update/download after the runtime is stable — usually transient.","Ensure the tokio runtime is not being dropped while downloads are in flight (await the update future before shutdown).","Inspect the wrapped JoinError message for a panic backtrace and fix the panic source if the closure itself is faulty.","Verify the multi-threaded runtime with blocking pool is used (not a current-thread runtime under heavy load).","Check disk health — pathological IO failures can surface here via unexpected paths."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match download_ytdlp_binary().await {\n    Err(e) if e.to_string().contains(\"spawn_blocking failed\") => {\n        // inspect JoinError (panic/cancel), ensure runtime alive, retry once\n    }\n    other => other?,\n}","preventionTips":["Await all background downloads before runtime shutdown.","Keep panics out of blocking closures; return Result instead.","Use a multi-threaded tokio runtime with adequate blocking threads.","Log JoinError details to distinguish panic from cancellation."],"tags":["tokio","spawn-blocking","runtime","async","rust"],"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"}