{"record":{"id":"1646190fabba51fa","repo":"tonhowtf/omniget","slug":"no-video-url","errorCode":null,"errorMessage":"No video URL","messagePattern":"No video URL","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/reddit.rs","lineNumber":544,"sourceCode":"                    file_size_bytes: None,\n                })\n            }\n        }\n    }\n\n    async fn native_download(\n        &self,\n        info: &MediaInfo,\n        opts: &DownloadOptions,\n        progress: mpsc::Sender<ProgressUpdate>,\n    ) -> anyhow::Result<DownloadResult> {\n        match info.media_type {\n            MediaType::Video => {\n                let video_quality = info\n                    .available_qualities\n                    .iter()\n                    .find(|q| q.label == \"video\")\n                    .ok_or_else(|| anyhow!(\"No video URL\"))?;\n\n                let audio_quality = info.available_qualities.iter().find(|q| q.label == \"audio\");\n\n                let has_audio = audio_quality.is_some();\n                let ffmpeg_available = ffmpeg::is_ffmpeg_available().await;\n\n                if has_audio && !ffmpeg_available {\n                    tracing::warn!(\"[reddit] Video has separate audio but FFmpeg is not installed — downloading video without audio\");\n                }\n\n                if has_audio {\n                    let video_tmp = opts.output_dir.join(format!(\n                        \"{}_video_tmp.mp4\",\n                        sanitize_filename::sanitize(&info.title)\n                    ));\n                    let audio_tmp = opts.output_dir.join(format!(\n                        \"{}_audio_tmp.mp4\",\n                        sanitize_filename::sanitize(&info.title)","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/reddit.rs#L526-L562","documentation":"For MediaType::Video posts, native_download searches available_qualities for an entry with label == \"video\". If media info was built without such an entry, the download path cannot proceed and throws \"No video URL\".","triggerScenarios":"native_download is called on MediaInfo whose media_type is Video but available_qualities contains no item labelled \"video\" — i.e. parse_media produced inconsistent state between media_type and qualities.","commonSituations":"Bug in parse_media that sets media_type without appending the video quality entry; partial/corrupt media JSON where DASH URLs are absent; race where media info came from a different code path.","solutions":["Check parse_media to ensure every Video-typed MediaInfo always pushes a \"video\"-labelled quality entry.","Re-fetch media info (native_get_media_info) in case the earlier fetch was incomplete.","Inspect info.available_qualities at the failure point to see which labels were actually produced.","Fall back to the post's fallback_url / HLS URL directly if the labelled entry is missing."],"exampleFix":"// before\nlet video_quality = info.available_qualities.iter()\n    .find(|q| q.label == \"video\")\n    .ok_or_else(|| anyhow!(\"No video URL\"))?;\n// after: graceful fallback to first video-like entry\nlet video_quality = info.available_qualities.iter()\n    .find(|q| q.label == \"video\")\n    .or_else(|| info.available_qualities.first())\n    .ok_or_else(|| anyhow!(\"No video URL\"))?;","handlingStrategy":"type-guard","validationCode":"// after getting MediaInfo, before download\nfn has_video_entry(info: &MediaInfo) -> bool {\n    info.media_type == MediaType::Video\n        && info.available_qualities.iter().any(|q| q.label == \"video\")\n}","typeGuard":"fn get_video_quality(info: &MediaInfo) -> Option<&Quality> {\n    if info.media_type != MediaType::Video { return None; }\n    info.available_qualities.iter().find(|q| q.label == \"video\")\n}","tryCatchPattern":"match native_download(opts).await {\n    Err(e) if e.to_string() == \"No video URL\" => {\n        // media info inconsistent: refetch and retry once\n        let fresh = get_media_info(url).await?;\n        retry_download(fresh).await?;\n    }\n    other => other,\n}","preventionTips":["Validate MediaInfo invariants (Video type implies a 'video' quality entry) before download.","Re-fetch media info before download if it was fetched long ago.","Add an assertion/log in parse_media whenever a Video MediaInfo is built without a video entry.","Keep parse_media and the download path's label conventions ('video'/'audio') in sync."],"tags":["reddit","download","internal-state","media"],"backgroundTag":"resource-not-found","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"}