tonhowtf/omniget · error
o yt-dlp devolveu um JSON que não deu para ler
Error message
o yt-dlp devolveu um JSON que não deu para ler: {e} What it means
Thrown by parse_listing in vimeo.rs when the JSON emitted by `yt-dlp --flat-playlist -J` cannot be deserialized with serde_json. It wraps the serde error, which includes position info. The library treats any yt-dlp stdout that is not valid JSON as fatal for listing operations.
Solutions
- Run the exact yt-dlp command manually (`yt-dlp --flat-playlist -J <url>`) and inspect what it prints to stdout.
- Update yt-dlp (`yt-dlp -U` or package manager) — Vimeo extraction breaks frequently and older versions emit errors instead of JSON.
- Ensure yt-dlp warnings go to stderr (add `--no-warnings` / correct `--progress` flags) so stdout is pure JSON.
- Check the serde error's `at line X column Y` offset to see what malformed content was returned.
Example fix
// before: trusting stdout blindly
let listing = parse_listing(&stdout)?;
// after: guard at the caller
if !stdout.trim_start().starts_with('{') {
anyhow::bail!("yt-dlp não devolveu JSON (saída: {})", &stdout[..stdout.len().min(200)]);
}
let listing = parse_listing(&stdout)?; Defensive patterns
Strategy: validation
Validate before calling
fn looks_like_json(s: &str) -> bool {
let t = s.trim_start();
t.starts_with('{') || t.starts_with('[')
}
// call before parse_listing:
if !looks_like_json(&stdout) { /* treat as yt-dlp failure, log stdout head */ } Type guard
fn is_json_object(s: &str) -> bool {
serde_json::from_str::<serde_json::Value>(s.trim()).map(|v| v.is_object()).unwrap_or(false)
} Try / catch
match parse_listing(&stdout) {
Err(e) if e.to_string().contains("não deu para ler") => {
eprintln!("yt-dlp não devolveu JSON; atualize o yt-dlp e rode o comando manualmente");
}
other => other?,
} Prevention
- Keep yt-dlp updated; Vimeo extractors break often
- Pass --no-warnings / route progress off stdout so output stays pure JSON
- Never spawn yt-dlp through a login shell whose rc files can print to stdout
- Log the first bytes of stdout when parsing fails to diagnose HTML/traceback contamination
When it happens
Trigger: Calling parse_listing (via the Vimeo listing/one/request paths) with stdout that is empty, HTML (e.g., a login or error page), a Python traceback, or JSON truncated by yt-dlp crashing mid-write.
Common situations: yt-dlp prints warnings/progress to stdout due to misconfigured flags; an old yt-dlp version outputs a different shape or crashes; a captive portal/proxy injects HTML; stdout gets polluted by shell profile output when spawned through a shell.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/1c721707eaacff95.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/vimeo.rs:652
let is_playlist = item.get("_type").and_then(|t| t.as_str()) == Some("playlist")
|| item.get("entries").is_some();
if is_playlist {
collect_entries(item, out);
continue;
}
if let Some(e) = entry_from_json(item) {
if !out.iter().any(|x| x.id == e.id && !e.id.is_empty()) {
out.push(e);
}
}
}
}
/// Lê o JSON do `--flat-playlist -J`. Aceita playlist (showcase, álbum,
/// canal), playlist aninhada e o caso degenerado de um vídeo só.
pub fn parse_listing(json: &str) -> Result<ParsedListing> {
let v: serde_json::Value = serde_json::from_str(json.trim())
.map_err(|e| anyhow!("o yt-dlp devolveu um JSON que não deu para ler: {e}"))?;
let id = v
.get("id")
.and_then(|x| x.as_str())
.unwrap_or_default()
.to_string();
let title = v
.get("title")
.and_then(|x| x.as_str())
.filter(|s| !s.trim().is_empty())
.unwrap_or(&id)
.to_string();
let mut entries = Vec::new();
collect_entries(&v, &mut entries);
if entries.is_empty() && v.get("entries").is_none() {
// Um vídeo só: o próprio objeto é a entrada.
if let Some(e) = entry_from_json(&v) {
entries.push(e);
}View on GitHub (pinned to 8600b91f42)