tonhowtf/omniget · error
Could not extract YouTube video ID
Error message
Could not extract YouTube video ID
What it means
Thrown by YouTubeDownloader::fetch_with_ytdlp when Self::extract_video_id(url) returns None for a non-playlist URL. It means the URL does not match any supported YouTube video URL shape, so the video ID cannot be parsed out of it.
Solutions
- Validate that the input is a YouTube watch/shorts/youtu.be URL before calling fetch_with_ytdlp.
- Normalize the URL: strip surrounding text, scheme, and unnecessary query parameters.
- Run Self::extract_video_id(url) as a pre-check and show a user-facing 'invalid YouTube URL' message on None.
- Extend extract_video_id to cover additional URL shapes (shorts, embed, live) if users commonly submit them.
Example fix
// before
let _video_id = Self::extract_video_id(url)
.ok_or_else(|| anyhow!("Could not extract YouTube video ID"))?;
// after: normalize before extracting
let cleaned = url.trim().split_whitespace().next().unwrap_or("");
let _video_id = Self::extract_video_id(cleaned)
.ok_or_else(|| anyhow!("Could not extract YouTube video ID from '{}'", cleaned))?; Defensive patterns
Strategy: type-guard
Validate before calling
if !youtube_url_is_valid(user_input) {
return Err(anyhow!("please paste a valid YouTube video URL (watch, youtu.be, or shorts)"));
}
fn youtube_url_is_valid(url: &str) -> bool {
url.contains("youtube.com/watch") || url.contains("youtu.be/") || url.contains("youtube.com/shorts/")
} Type guard
fn has_extractable_video_id(url: &str) -> bool {
YouTubeDownloader::extract_video_id(url.trim()).is_some()
} Try / catch
match YouTubeDownloader::extract_video_id(url.trim()) {
Some(id) => proceed_with(id),
None => {
eprintln!("invalid YouTube URL: '{}' — expected a watch/youtu.be/shorts link", url);
return;
}
} Prevention
- Validate/normalize user-pasted URLs before calling the downloader.
- Trim whitespace and strip surrounding text from clipboard input.
- Support common YouTube URL shapes (watch, youtu.be, shorts, embed) in the UI.
- Show a clear 'not a YouTube video URL' message at input time.
- Redirect channel/playlist/search URLs to the appropriate handlers instead.
When it happens
Trigger: Calling fetch_with_ytdlp with a non-YouTube URL, a YouTube URL in an unsupported shape (e.g. youtu.be with extra junk, /shorts/ variants if unhandled, mangled query strings), or an empty/whitespace string.
Common situations: Users pasting search-result pages, channel URLs, or music.youtube.com links; URLs wrapped in extra text; regional YouTube domains the extractor doesn't recognize; mobile share links with redirects.
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
- nao reconheci um video do YouTube em
- nao reconheci um video do YouTube em
- não reconheci o vídeo do YouTube
- não reconheci esse perfil ou coleção
- Could not extract post ID from Threads URL
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/453aa933c1d95af6.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/platforms/youtube/mod.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)