{"record":{"id":"3c5e2aae9bfa7455","repo":"tonhowtf/omniget","slug":"yt-dlp-not-found-mod","errorCode":null,"errorMessage":"yt-dlp not found","messagePattern":"yt-dlp not found","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/douyin/mod.rs","lineNumber":189,"sourceCode":"#[async_trait]\nimpl PlatformDownloader for DouyinDownloader {\n    fn name(&self) -> &str {\n        \"douyin\"\n    }\n\n    fn can_handle(&self, url: &str) -> bool {\n        if let Ok(parsed) = url::Url::parse(url) {\n            if let Some(host) = parsed.host_str() {\n                return Self::host_matches(host);\n            }\n        }\n        false\n    }\n\n    async fn get_media_info(&self, url: &str) -> anyhow::Result<MediaInfo> {\n        let ytdlp_path = ytdlp::find_ytdlp_cached()\n            .await\n            .ok_or_else(|| anyhow!(\"yt-dlp not found\"))?;\n\n        let resolved = Self::resolve_url(url).await;\n        let extra = Self::extra_flags();\n        let json = ytdlp::get_video_info(&ytdlp_path, &resolved, &extra).await?;\n\n        let title = json\n            .get(\"title\")\n            .and_then(|v| v.as_str())\n            .unwrap_or(\"Douyin Video\")\n            .to_string();\n\n        let author = json\n            .get(\"uploader\")\n            .and_then(|v| v.as_str())\n            .or_else(|| json.get(\"channel\").and_then(|v| v.as_str()))\n            .unwrap_or(\"Unknown\")\n            .to_string();\n","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/douyin/mod.rs#L171-L207","documentation":"`get_media_info` for Douyin requires the external yt-dlp binary and errors when `ytdlp::find_ytdlp_cached()` returns None. The library shells out to yt-dlp for metadata extraction, so without the binary on PATH (or a cached path) it cannot resolve media info.","triggerScenarios":"Calling Douyin `get_media_info` when yt-dlp is neither at `opts.ytdlp_path`-like configuration nor discoverable via `find_ytdlp_cached` (not installed, not on PATH, or the cache holds a stale/deleted path).","commonSituations":"Fresh machine/container without yt-dlp installed, yt-dlp installed in a venv not on the app's PATH, yt-dlp upgraded/moved after the cache was populated, or bundled-binary download failed at startup.","solutions":["Install yt-dlp (e.g. `pip install yt-dlp` or `brew install yt-dlp`) so it is on the app's PATH.","Verify with `yt-dlp --version` in the same environment the Tauri app runs in.","Clear/refresh the ytdlp path cache if the binary was moved or upgraded.","Ensure the app's dependency auto-download/update routine ran (check startup logs)."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Rust, before get_media_info\nif ytdlp::find_ytdlp_cached().await.is_none() {\n    return Err(anyhow!(\"yt-dlp must be installed before using Douyin extraction\"));\n}","typeGuard":null,"tryCatchPattern":"// Rust\nlet ytdlp_path = match ytdlp::find_ytdlp_cached().await {\n    Some(p) => p,\n    None => {\n        log::warn!(\"yt-dlp not found; attempting managed install\");\n        ytdlp::install_ytdlp().await? // fall back to auto-install\n    }\n};","preventionTips":["Run a startup dependency check that installs/updates yt-dlp before accepting jobs.","Pin a known-good yt-dlp path in app config instead of relying on PATH lookups.","Watch for yt-dlp version staleness —Douyin extraction breaks without frequent updates."],"tags":["dependency","yt-dlp","douyin","missing-binary"],"backgroundTag":"missing-dependency","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"}