tonhowtf/omniget · error
yt-dlp playlist failed
Error message
yt-dlp playlist failed: {} What it means
When the playlist yt-dlp run exits non-zero, the code extracts a human-readable message from stderr with extract_error_message and returns it wrapped in this error. It means yt-dlp itself failed on the playlist URL — the wrapper is relaying yt-dlp's own diagnostic.
Solutions
- Update yt-dlp to the latest version — most extractor failures are fixed upstream
- Check the embedded stderr message: handle 429 with backoff, auth errors by refreshing cookies
- Verify the playlist URL is public and correctly formed
- Retry with different player clients or add browser cookies via --cookies-from-browser
Example fix
// before
return Err(anyhow!("yt-dlp playlist failed: {}", extract_error_message(&stderr)));
// after
if stderr_lower.contains("http error 429") {
rate_limit_429_increment();
return Err(anyhow!("yt-dlp playlist failed (rate limited, retry later): {}", extract_error_message(&stderr)));
}
return Err(anyhow!("yt-dlp playlist failed: {}", extract_error_message(&stderr))); Defensive patterns
Strategy: fallback
Validate before calling
// Preflight: confirm yt-dlp can reach the site with a cheap single-item probe
let probe = ytdlp_command(ytdlp)
.args(["--flat-playlist", "--playlist-items", "1", "--dump-json", url])
.output()
.await;
if !probe.map(|o| o.status.success()).unwrap_or(false) {
return Err("playlist URL rejected by yt-dlp preflight; check URL/auth/yt-dlp version".into());
} Try / catch
match get_playlist_info(url).await {
Err(e) if e.to_string().contains("http error 429") => wait_and_retry_with_backoff(url),
Err(e) if e.to_string().contains("yt-dlp playlist failed") => try_fallback_extractor_or_notify(e),
other => other,
} Prevention
- Keep yt-dlp updated; most non-zero exits are extractor breakage fixed upstream
- Honor the app's 429 rate-limit tracking with real backoff before retries
- Require cookies/credentials for private playlists and refresh them proactively
- Validate playlist URLs before submission
When it happens
Trigger: yt-dlp exits with failure while listing a playlist: HTTP 429 rate limiting (tracked separately), unsupported/private/deleted playlist, geo-block, signature/extractor breakage from an outdated yt-dlp, or bad cookies.
Common situations: Outdated yt-dlp after a YouTube layout change; rate-limited IPs on shared hosts; private or members-only playlists without valid cookies; URLs that are not actually playlists.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/db4a967bb960bee3.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/ytdlp.rs:2606
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
let stderr_lower = stderr.to_lowercase();
if stderr_lower.contains("http error 429") {
rate_limit_429_increment();
let sanitized_url = sanitize_log_line(url);
let player_client = if is_youtube_url(url) {
"default"
} else {
"n/a"
};
tracing::warn!(
"[yt-429] rate limit in get_playlist_info: url={} player_client={} retries=3",
sanitized_url,
player_client
);
}
return Err(anyhow!(
"yt-dlp playlist failed: {}",
extract_error_message(&stderr)
));
}
let stdout = String::from_utf8_lossy(&output.stdout);
Ok(parse_playlist_dump(&stdout, url))
}
fn parse_playlist_dump(stdout: &str, source_url: &str) -> (String, Vec<PlaylistEntry>) {
let mut entries = Vec::new();
let mut playlist_title = String::new();
let source_is_youtube = is_youtube_url(source_url);
for line in stdout.lines() {
if line.trim().is_empty() {
continue;
}View on GitHub (pinned to 8600b91f42)