{"record":{"id":"1c721707eaacff95","repo":"tonhowtf/omniget","slug":"o-yt-dlp-devolveu-um-json-que-n-o-deu-para-ler-e","errorCode":null,"errorMessage":"o yt-dlp devolveu um JSON que não deu para ler: {e}","messagePattern":"o yt-dlp devolveu um JSON que não deu para ler: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/vimeo.rs","lineNumber":652,"sourceCode":"        let is_playlist = item.get(\"_type\").and_then(|t| t.as_str()) == Some(\"playlist\")\n            || item.get(\"entries\").is_some();\n        if is_playlist {\n            collect_entries(item, out);\n            continue;\n        }\n        if let Some(e) = entry_from_json(item) {\n            if !out.iter().any(|x| x.id == e.id && !e.id.is_empty()) {\n                out.push(e);\n            }\n        }\n    }\n}\n\n/// Lê o JSON do `--flat-playlist -J`. Aceita playlist (showcase, álbum,\n/// canal), playlist aninhada e o caso degenerado de um vídeo só.\npub fn parse_listing(json: &str) -> Result<ParsedListing> {\n    let v: serde_json::Value = serde_json::from_str(json.trim())\n        .map_err(|e| anyhow!(\"o yt-dlp devolveu um JSON que não deu para ler: {e}\"))?;\n    let id = v\n        .get(\"id\")\n        .and_then(|x| x.as_str())\n        .unwrap_or_default()\n        .to_string();\n    let title = v\n        .get(\"title\")\n        .and_then(|x| x.as_str())\n        .filter(|s| !s.trim().is_empty())\n        .unwrap_or(&id)\n        .to_string();\n    let mut entries = Vec::new();\n    collect_entries(&v, &mut entries);\n    if entries.is_empty() && v.get(\"entries\").is_none() {\n        // Um vídeo só: o próprio objeto é a entrada.\n        if let Some(e) = entry_from_json(&v) {\n            entries.push(e);\n        }","sourceCodeStart":634,"sourceCodeEnd":670,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/vimeo.rs#L634-L670","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: trusting stdout blindly\nlet listing = parse_listing(&stdout)?;\n// after: guard at the caller\nif !stdout.trim_start().starts_with('{') {\n    anyhow::bail!(\"yt-dlp não devolveu JSON (saída: {})\", &stdout[..stdout.len().min(200)]);\n}\nlet listing = parse_listing(&stdout)?;","handlingStrategy":"validation","validationCode":"fn looks_like_json(s: &str) -> bool {\n    let t = s.trim_start();\n    t.starts_with('{') || t.starts_with('[')\n}\n// call before parse_listing:\nif !looks_like_json(&stdout) { /* treat as yt-dlp failure, log stdout head */ }","typeGuard":"fn is_json_object(s: &str) -> bool {\n    serde_json::from_str::<serde_json::Value>(s.trim()).map(|v| v.is_object()).unwrap_or(false)\n}","tryCatchPattern":"match parse_listing(&stdout) {\n    Err(e) if e.to_string().contains(\"não deu para ler\") => {\n        eprintln!(\"yt-dlp não devolveu JSON; atualize o yt-dlp e rode o comando manualmente\");\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["json","yt-dlp","vimeo","serde"],"backgroundTag":"json-parse-error","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}