{"record":{"id":"37e64e568c181d6a","repo":"tonhowtf/omniget","slug":"vimeo-requires-yt-dlp-failed-to-get-yt-dlp","errorCode":null,"errorMessage":"Vimeo requires yt-dlp. Failed to get yt-dlp: {}","messagePattern":"Vimeo requires yt-dlp\\. Failed to get yt-dlp: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/vimeo.rs","lineNumber":131,"sourceCode":"impl PlatformDownloader for VimeoDownloader {\n    fn name(&self) -> &str {\n        \"vimeo\"\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                let host = host.to_lowercase();\n                return host == \"vimeo.com\" || host.ends_with(\".vimeo.com\");\n            }\n        }\n        false\n    }\n\n    async fn get_media_info(&self, url: &str) -> anyhow::Result<MediaInfo> {\n        let ytdlp_path = ytdlp::ensure_ytdlp()\n            .await\n            .map_err(|e| anyhow!(\"Vimeo requires yt-dlp. Failed to get yt-dlp: {}\", e))?;\n\n        let json = ytdlp::get_video_info(&ytdlp_path, url, &[]).await?;\n        Self::parse_video_info(&json)\n    }\n\n    async fn download(\n        &self,\n        info: &MediaInfo,\n        opts: &DownloadOptions,\n        progress: mpsc::Sender<ProgressUpdate>,\n    ) -> anyhow::Result<DownloadResult> {\n        let _ = progress.send(ProgressUpdate::percent(0.0)).await;\n\n        let ytdlp_path = ytdlp::ensure_ytdlp().await?;\n\n        let first = info\n            .available_qualities\n            .first()","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/vimeo.rs#L113-L149","documentation":"Vimeo's `get_media_info` (src-tauri/omniget-core/src/platforms/vimeo.rs:131) does not implement a native API path; it delegates entirely to an external `yt-dlp` binary obtained via `ytdlp::ensure_ytdlp()`. If that setup step fails (download of the binary fails, no network, Python missing, unsupported platform, etc.), the error is wrapped with this 'Vimeo requires yt-dlp' prefix so the user knows the external tool is mandatory.","triggerScenarios":"Any call to native_get_media_info with a Vimeo URL where ytdlp::ensure_ytdlp() fails: yt-dlp binary not present and auto-download blocked (offline, proxy, disk permissions), download URL unreachable, checksum/location invalid, or the binary is present but not executable.","commonSituations":"First run on an air-gapped or firewalled machine that can't download yt-dlp, antivirus quarantining the downloaded binary, Linux/macOS binary lacking +x permission, unsupported CPU/arch build, or a stale pinned yt-dlp version broken by a Vimeo page change.","solutions":["Ensure network access to the yt-dlp release host (GitHub releases) or pre-install yt-dlp so ensure_ytdlp finds it on PATH.","Manually install yt-dlp (pip install yt-dlp or package manager) and confirm `yt-dlp --version` runs from the shell.","On Unix, chmod +x the yt-dlp binary if the downloaded executable lacks the permission bit.","Update yt-dlp to the latest release — Vimeo extraction breaks often with old versions.","Check disk space and antivirus/Defender logs if ensure_ytdlp's wrapped inner error indicates the download itself failed."],"exampleFix":"// before: hard failure when yt-dlp can't be ensured\nlet ytdlp_path = ytdlp::ensure_ytdlp()\n    .await\n    .map_err(|e| anyhow!(\"Vimeo requires yt-dlp. Failed to get yt-dlp: {}\", e))?;\n\n// after: fall back to a system-installed yt-dlp\nlet ytdlp_path = match ytdlp::ensure_ytdlp().await {\n    Ok(p) => p,\n    Err(e) => ytdlp::find_system_ytdlp()\n        .ok_or_else(|| anyhow!(\"Vimeo requires yt-dlp. Failed to get yt-dlp: {}\", e))?,\n};","handlingStrategy":"validation","validationCode":"// Verify yt-dlp availability before calling any Vimeo API\nlet ytdlp_ready = tokio::process::Command::new(\"yt-dlp\")\n    .arg(\"--version\")\n    .output()\n    .await\n    .map(|o| o.status.success())\n    .unwrap_or(false);\nif !ytdlp_ready {\n    eprintln!(\"yt-dlp missing or not executable — install it (pip install yt-dlp) before fetching Vimeo media\");\n}","typeGuard":"fn ytdlp_available(path: &std::path::Path) -> bool {\n    path.exists() && {\n        #[cfg(unix)]\n        { std::os::unix::fs::PermissionsExt::mode(&path.metadata().unwrap().permissions()) & 0o111 != 0 }\n        #[cfg(not(unix))]\n        { path.is_file() }\n    }\n}","tryCatchPattern":"match vimeo.get_media_info(url).await {\n    Ok(info) => use_media(info),\n    Err(e) if e.to_string().starts_with(\"Vimeo requires yt-dlp\") => {\n        // install/repair yt-dlp, then retry once\n        ytdlp::ensure_ytdlp().await.unwrap_or_else(|ie| {\n            panic!(\"cannot auto-provision yt-dlp: {ie}; install manually\");\n        });\n        retry_once(vimeo.get_media_info(url)).await\n    }\n    Err(e) => report(e),\n}","preventionTips":["Pre-install yt-dlp on the machine (pip install yt-dlp) instead of relying on first-run auto-download.","Allow network egress to GitHub releases so ensure_ytdlp can download/update the binary.","Ensure the yt-dlp binary has execute permission on Unix (chmod +x).","Exclude the binary location from antivirus quarantine rules.","Keep yt-dlp updated — Vimeo extraction breaks with stale versions."],"tags":["external-dependency","yt-dlp","vimeo","dependency-missing"],"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"}