tonhowtf/omniget · error
yt-dlp
Error message
yt-dlp: {} What it means
Fallback error for classified yt-dlp failures: when none of the specific stderr patterns matched, the wrapper takes the last error line from yt-dlp's stderr (truncated to 300 chars) and wraps it as anyhow!("yt-dlp: {}"). It represents any unmatched yt-dlp failure.
Solutions
- Read the embedded yt-dlp message after the 'yt-dlp:' prefix — it is the actual root cause
- Update yt-dlp to the latest release; most extractor errors are fixed upstream
- Re-run manually with `yt-dlp -v <url>` for verbose diagnostics
- Check rate-limit stats (get_rate_limit_stats) if the message mentions HTTP 429
Example fix
// before
// unmatched stderr -> error swallowed or generic panic
// after
let last_error_line = stderr.lines().rev().find(|l| !l.trim().is_empty());
anyhow!("yt-dlp: {}", msg) Defensive patterns
Strategy: try-catch
Validate before calling
// keep yt-dlp current; stale extractors cause most unmatched errors
let version = tokio::process::Command::new(&ytdlp).arg("--version").output().await?;
if is_outdated(&version) { prompt_update(); } Try / catch
match result {
Err(e) if e.to_string().starts_with("yt-dlp: ") => {
log::error!("unclassified yt-dlp failure: {e}");
show_verbose_log_hint(&e);
}
other => other?,
} Prevention
- Always log the full stderr for unmatched failures
- Prompt users to update yt-dlp when errors repeat
- Offer a 'copy verbose log' action for bug reports
- Track 429s via get_rate_limit_stats and back off
When it happens
Trigger: Any yt-dlp exit failure whose stderr does not match earlier patterns: extractor exceptions, HTTP 403/429 on fragments, postprocessing errors, disk-space errors, or yt-dlp crashes.
Common situations: New site-side changes producing novel errors, yt-dlp version too old for a site, transient CDN errors, or very long/verbose stderr hiding the root cause.
Related errors
- {}
- {}
- busca falhou
- Connection timed out. Check your internet and try again.
- Download reported success but no matching file appeared in
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/4ce66e6eefb3b773.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/ytdlp.rs:4520
.unwrap_or("")
.trim();
let msg = if !last_error_line.is_empty() {
last_error_line
.strip_prefix("ERROR: ")
.or_else(|| last_error_line.strip_prefix("ERROR:"))
.or_else(|| last_error_line.strip_prefix("error: "))
.unwrap_or(last_error_line)
} else {
let trimmed = stderr.trim();
if trimmed.len() > 300 {
&trimmed[..300]
} else {
trimmed
}
};
anyhow!("yt-dlp: {}", msg)
}
pub fn get_rate_limit_stats() -> serde_json::Value {
serde_json::json!({
"rate_limit_429_count": RATE_LIMIT_429_COUNT.load(Ordering::Relaxed)
})
}
/// Corpo de uma linha do nosso `--progress-template`.
///
/// O `download:` no início do template é consumido pelo yt-dlp como o *tipo*
/// da template (`[TYPES:]TEMPLATE`), então a linha impressa começa direto
/// pelo percentual: ` 0.5%|eta:NA|spd:…`. Reconhecemos a linha pelos campos
/// que só o nosso template tem (`|eta:` e `|spd:`), com o prefixo opcional
/// para o caso de o yt-dlp mudar de ideia.
fn template_body(line: &str) -> Option<&str> {
let t = line.trim();
if let Some(rest) = t.strip_prefix("download:") {View on GitHub (pinned to 8600b91f42)