tonhowtf/omniget · error

yt-dlp not found

Error message

yt-dlp not found

What it means

During download of a non-direct (yt-dlp-playable) video quality, the library needs the yt-dlp binary. It uses opts.ytdlp_path if provided; otherwise it calls find_ytdlp_cached(), and if that returns None it fails with the shorter 'yt-dlp not found' message.

Solutions

  1. Install yt-dlp (pip install -U yt-dlp / brew install yt-dlp) or use the app Settings installer.
  2. Pass opts.ytdlp_path pointing at an explicit yt-dlp binary.
  3. Confirm `yt-dlp --version` works in the same environment/user as the app.
  4. If a cached binary is broken, clear the app cache so find_ytdlp_cached() re-resolves it.

Example fix

// before: download fails at runtime
let opts = DownloadOpts { ytdlp_path: None, ..Default::default() };
tiktok.download(&info, &opts).await?;
// after: resolve yt-dlp up front
let ytdlp = opts.ytdlp_path.clone()
    .or_else(crate::core::ytdlp::resolve_on_disk())
    .ok_or_else(|| anyhow!("yt-dlp not found — install it in Settings"))?;
let opts = DownloadOpts { ytdlp_path: Some(ytdlp), ..opts };
tiktok.download(&info, &opts).await?;
Defensive patterns

Strategy: validation

Validate before calling

// resolve before download, not inside it
let ytdlp = opts.ytdlp_path.clone().or_else(find_ytdlp_on_disk)
    .ok_or_else(|| anyhow!("yt-dlp not found — install it in Settings"))?;

Type guard

fn ytdlp_available(opts: &DownloadOpts) -> bool {
    opts.ytdlp_path.as_ref().map(|p| p.exists()).unwrap_or(false)
        || std::process::Command::new("yt-dlp").arg("--version").output().map(|o| o.status.success()).unwrap_or(false)
}

Try / catch

match tiktok.download(&info, &opts).await {
    Err(e) if e.to_string() == "yt-dlp not found" => Err(UserActionRequired::InstallYtdlp),
    other => other,
}

Prevention

When it happens

Trigger: download() selects a quality whose format is not tiktok_direct, opts.ytdlp_path is None, and find_ytdlp_cached() finds no yt-dlp executable on PATH or in the app cache.

Common situations: yt-dlp never installed or removed from PATH; running the app in a clean environment/container; yt-dlp auto-update breaking the cached path; direct URL expired so the download fell back to the yt-dlp path where the binary is missing.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/e2b3f86e2daa2a4e. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/tiktok.rs:579

                                duration_seconds: info.duration_seconds.unwrap_or(0.0),
                                torrent_id: None,
                            });
                        }
                        Err(e) => {
                            tracing::warn!(
                                "[tiktok] direct download failed: {}, falling back to yt-dlp",
                                e
                            );
                            let _ = tokio::fs::remove_file(&output).await;
                        }
                    }
                }

                let ytdlp_path = match &opts.ytdlp_path {
                    Some(p) => p.clone(),
                    None => crate::core::ytdlp::find_ytdlp_cached()
                        .await
                        .ok_or_else(|| anyhow!("yt-dlp not found"))?,
                };

                crate::core::ytdlp::download_video(
                    &ytdlp_path,
                    &quality.url,
                    &opts.output_dir,
                    None,
                    progress,
                    opts.download_mode.as_deref(),
                    None,
                    opts.filename_template.as_deref(),
                    opts.referer.as_deref().or(Some("https://www.tiktok.com/")),
                    opts.cancel_token.clone(),
                    None,
                    opts.concurrent_fragments,
                    false,
                    &[],
                    opts.audio_format.as_deref(),

View on GitHub (pinned to 8600b91f42)