tonhowtf/omniget · error
gallery-dl binary not found after download
Error message
gallery-dl binary not found after download
What it means
After the spawn_blocking write step completes without error, download_gallerydl verifies the target binary path exists. If the file is missing on disk it throws 'gallery-dl binary not found after download', an internal consistency check: the task reported success but produced no file.
Solutions
- Check whether antivirus/EDR quarantined the new binary and add an exclusion for the app's bin directory
- Log the exact target path and verify manually that it exists after a failed run
- Ensure the write path inside spawn_blocking and `target` are built from the same bin_name/path logic
- Re-run the download — a transient FS sync issue on network shares can delay visibility
- Add a retry or re-download step when the existence check fails
Example fix
// before
if !target.exists() {
return Err(anyhow!("gallery-dl binary not found after download"));
}
// after
if !target.exists() {
anyhow::bail!(
"gallery-dl binary not found at {} after download (AV quarantine or path mismatch?)",
target.display()
);
} Defensive patterns
Strategy: validation
Validate before calling
let target = bin_dir.join(bin_name("gallery-dl"));
if !bin_dir.exists() || !bin_dir.join(bin_name("gallery-dl")).parent().map(|p| p.exists()).unwrap_or(false) {
return Err(anyhow!("target directory {} missing before download", bin_dir.display()));
} Type guard
fn binary_ready(target: &std::path::Path) -> bool {
target.is_file() && std::fs::metadata(target).map(|m| m.len() > 0).unwrap_or(false)
} Try / catch
match ensure_gallerydl().await {
Ok(p) => p,
Err(e) if e.to_string().contains("binary not found after download") => {
// file vanished post-write: suspect AV quarantine or path mismatch
log::error!("gallery-dl missing at target after install: {e}");
Err(anyhow!("installed binary was removed (antivirus?) — add exclusion and retry"))
}
Err(e) => Err(e),
} Prevention
- Whitelist the app's managed-bin directory in antivirus/EDR software
- Assert the write path and existence-check path are derived from the same bin_name() call
- Verify file size > 0 after download, not just existence
- Build the target path in one place and pass it into both the writer and the checker
When it happens
Trigger: The spawn_blocking closure returned Ok without actually writing the file (e.g. a skipped/conditional write branch), the target path was moved/deleted between write and the existence check, or the binary was written to a different path than `target` (path/perm_dir mismatch).
Common situations: Antivirus quarantining the freshly downloaded executable immediately after write; the extraction/permissions branch silently skipping the rename/write; target path computed with a different bin_name than where bytes were written; network drives with delayed visibility.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Write error (disk full?)
- rename .part to final failed
- caminho de modelo sem pasta
- binario sumiu apos instalar
- whisper-cli sumiu depois de mover a pasta
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/9227e49cfe8f199c.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/dependencies.rs:855
let bytes = response.bytes().await?;
let data = bytes.to_vec();
let target_clone = target.clone();
tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
std::fs::write(&target_clone, &data)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perm = std::fs::metadata(&target_clone)?.permissions();
perm.set_mode(0o755);
std::fs::set_permissions(&target_clone, perm)?;
}
Ok(())
})
.await
.map_err(|e| anyhow!("Spawn blocking failed: {}", e))??;
if !target.exists() {
return Err(anyhow!("gallery-dl binary not found after download"));
}
Ok(target)
}
pub async fn ensure_aria2c() -> Option<PathBuf> {
if let Some(path) = find_tool("aria2c").await {
return Some(path);
}
// Auto-download only on Windows
#[cfg(target_os = "windows")]
{
match download_aria2c().await {
Ok(path) => return Some(path),
Err(e) => {
tracing::warn!("Failed to download aria2c: {}", e);
}View on GitHub (pinned to 8600b91f42)