tonhowtf/omniget · error

Could not extract YouTube video ID

Error message

Could not extract YouTube video ID

What it means

Raised in fetch_with_ytdlp when Self::extract_video_id(url) returns None, i.e. the URL passed to the YouTube platform handler does not contain a recognizable video ID. The code checks for playlist/media-type results first; anything that falls through must be a single video, so a non-video URL aborts here before yt-dlp is invoked.

Solutions

  1. Validate the URL is a YouTube video URL (watch?v=, youtu.be/<id>, shorts/<id>) before calling fetch_with_ytdlp.
  2. Check the URL for typos, missing query parameters, or surrounding whitespace/HTML markup from copy-paste.
  3. If the target is a playlist or channel, use the playlist/media-type code path instead of the single-video path.
  4. Extend extract_video_id if a legitimate new YouTube URL format (e.g. /live/<id>) is not being matched.

Example fix

// before
let url = input.trim();
platform.fetch_with_ytdlp(url, &ytdlp).await?;

// after
let url = input.trim();
if extract_video_id(url).is_none() {
    eprintln!("not a YouTube video URL: {url}");
    return Ok(()); // or route to playlist handling
}
platform.fetch_with_ytdlp(url, &ytdlp).await?;
Defensive patterns

Strategy: validation

Validate before calling

const YT_VIDEO_RE = /^https?:\/\/(www\.|m\.)?(youtube\.com\/(watch\?v=|shorts\/|live\/)|youtu\.be\/)[\w-]{11}/;
if (!YT_VIDEO_RE.test(url.trim())) throw new Error(`not a YouTube video URL: ${url}`);

Type guard

function isYouTubeVideoUrl(url) {
  try { const u = new URL(url); return u.hostname.endsWith('youtube.com') || u.hostname === 'youtu.be'; }
  catch { return false; }
}

Prevention

When it happens

Trigger: Calling fetch_with_ytdlp with a YouTube URL that is not a watch/shorts/youtu.be video URL (e.g. a channel URL, a youtu.be link missing its ID, a URL with only a 'v=' parameter that is empty, or an already-extracted playlist that failed the earlier Playlist branch).

Common situations: Passing user-supplied URLs straight from a UI or clipboard without validation; passing youtube.com URLs for /feed, /channel, /c, /results (search) pages; truncated URLs pasted without the video ID; URLs to live-set or mix pages with unexpected path shapes.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/youtube.rs:115

                    url: entry.url,
                    format: "ytdlp_playlist".to_string(),
                })
                .collect();

            return Ok(MediaInfo {
                title: sanitize_filename::sanitize(&playlist_title),
                author: playlist_title,
                platform: "youtube".to_string(),
                duration_seconds: None,
                thumbnail_url: None,
                available_qualities: qualities,
                media_type: MediaType::Playlist,
                file_size_bytes: None,
            });
        }

        let _video_id = Self::extract_video_id(url)
            .ok_or_else(|| anyhow!("Could not extract YouTube video ID"))?;

        let json = ytdlp::get_video_info(ytdlp_path, url, &[]).await?;
        Self::parse_video_info(&json)
    }

    fn extract_quality_height(quality_str: &str) -> Option<u32> {
        let s = quality_str.trim().to_lowercase();
        if s == "best" || s == "highest" {
            return None;
        }
        s.trim_end_matches('p').parse::<u32>().ok()
    }

    pub fn parse_video_info(json: &serde_json::Value) -> anyhow::Result<MediaInfo> {
        let video_id = json
            .get("id")
            .and_then(|v| v.as_str())
            .unwrap_or("unknown")

View on GitHub (pinned to 8600b91f42)