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

  1. Check whether antivirus/EDR quarantined the new binary and add an exclusion for the app's bin directory
  2. Log the exact target path and verify manually that it exists after a failed run
  3. Ensure the write path inside spawn_blocking and `target` are built from the same bin_name/path logic
  4. Re-run the download — a transient FS sync issue on network shares can delay visibility
  5. 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

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


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)