{"record":{"id":"d5f5cb7d6bac1479","repo":"tonhowtf/omniget","slug":"no-quality-available-d5f5cb","errorCode":null,"errorMessage":"No quality available","messagePattern":"No quality available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/platforms/youtube/mod.rs","lineNumber":344,"sourceCode":"        } else {\n            ytdlp::ensure_ytdlp().await?\n        };\n\n        let quality_height = opts\n            .quality\n            .as_deref()\n            .and_then(Self::extract_quality_height);\n\n        if info.media_type == MediaType::Playlist {\n            return self\n                .download_playlist(info, opts, progress, &ytdlp_path, quality_height)\n                .await;\n        }\n\n        let first = info\n            .available_qualities\n            .first()\n            .ok_or_else(|| anyhow!(\"No quality available\"))?;\n\n        let selected = match quality_height {\n            Some(h) => info\n                .available_qualities\n                .iter()\n                .filter(|q| q.height > 0 && q.height <= h)\n                .max_by_key(|q| q.height)\n                .unwrap_or(first),\n            None => first,\n        };\n        let video_url = &selected.url;\n\n        ytdlp::download_video(\n            &ytdlp_path,\n            video_url,\n            &opts.output_dir,\n            quality_height,\n            progress,","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/platforms/youtube/mod.rs#L326-L362","documentation":"During download, the code fetches video info and picks a quality: either the requested height (quality_height) or the first entry of available_qualities as a default. If the list is empty, .first() returns None and the code raises this error rather than downloading blindly. It means yt-dlp returned metadata containing no usable format entries.","triggerScenarios":"Calling download on a video whose parsed info has an empty available_qualities list: formats-only/dash-limited videos, region-blocked or age-restricted videos where yt-dlp got metadata but no formats, or parse_video_info filtering out all formats (e.g. audio-only entries, height<=0).","commonSituations":"Age-restricted video without cookies; live stream currently offline; yt-dlp version too old for a recent YouTube throttling change so format extraction silently yields nothing; a private/deleted video where info parsing produced an empty quality list.","solutions":["Run yt-dlp manually (yt-dlp -F <url>) to see whether any formats are actually available.","Update yt-dlp to the latest release — empty format lists are usually a YouTube extraction regression.","For age-restricted content, supply cookies to yt-dlp and retry.","Handle the error in callers by reporting 'no downloadable formats' to the user rather than retrying the same video."],"exampleFix":"// caller-side guard\nlet info = get_media_info(url).await?;\nif info.available_qualities.is_empty() {\n    return Err(anyhow!(\"video has no downloadable formats\"));\n}\ndownload(url, Some(1080)).await?;","handlingStrategy":"validation","validationCode":"let info = get_media_info(url).await?;\nif info.available_qualities.is_empty() {\n    return Err(anyhow!(\"no downloadable formats for {}\", url));\n}","typeGuard":"fn has_qualities(info: &MediaInfo) -> bool { !info.available_qualities.is_empty() }","tryCatchPattern":"match download(url, Some(1080)).await {\n    Err(e) if e.to_string() == \"No quality available\" => {\n        eprintln!(\"Video exposes no downloadable formats; try cookies or update yt-dlp\");\n    }\n    r => r?,\n}","preventionTips":["Keep yt-dlp updated — empty format lists usually mean an extraction regression","Supply cookies for age-restricted or members-only videos","Pre-check available_qualities before choosing a height","Treat empty quality lists as 'video unavailable', not transient"],"tags":["youtube","qualities","empty-list","yt-dlp"],"backgroundTag":"empty-result-set","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"}