tonhowtf/omniget · error · anyhow::Error

o JSON do yt-dlp não foi lido

Error message

o JSON do yt-dlp não foi lido: {}

What it means

`ytdlp_json` found a stdout line starting with '{' but `serde_json::from_str` failed to parse it, producing "o JSON do yt-dlp não foi lido". This means yt-dlp emitted something JSON-like that is not the expected single-line JSON object — typically truncated output or an unexpected shape.

Solutions

  1. Update yt-dlp to the latest stable version so `-j` output matches the parser's expectations.
  2. Run yt-dlp manually with the same args and inspect the raw JSON line for truncation or noise.
  3. Ensure the child process is fully drained (stdout read to EOF) before parsing.
  4. If parsing must be lenient, fall back to locating the full JSON object instead of the first '{'-prefixed line.

Example fix

// before
serde_json::from_str(line).map_err(|e| anyhow!("o JSON do yt-dlp não foi lido: {}", e))?
// after
let v: serde_json::Value = serde_json::from_str(line)
    .map_err(|e| anyhow!("o JSON do yt-dlp não foi lido: {}; line={}", e, &line[..line.len().min(200)]))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Drain the full stdout and confirm the first non-empty line parses before trusting it
let line = text.lines().map(str::trim).find(|l| l.starts_with('{')).unwrap_or("");
serde_json::from_str::<serde_json::Value>(line).is_ok()

Try / catch

match serde_json::from_str::<serde_json::Value>(line) {
    Ok(v) => Ok(v),
    Err(e) => Err(anyhow!("JSON inválido do yt-dlp ({e}); saída: {}", truncate(line, 200))),
}

Prevention

When it happens

Trigger: yt-dlp's stdout line starting with '{' is truncated (pipe closed early, output limit) or is not valid JSON (progress lines interleaved, multi-line pretty JSON picked mid-stream); a yt-dlp version changed its `--dump-json`/`-j` output format.

Common situations: Running a very old or patched yt-dlp whose JSON schema differs; process killed mid-write; wrapping the binary with a script that prints banners; encoding issues corrupting the line.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/33ae1058e37dc87f. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/tiktok/mod.rs:759

    cmd.args(args)
        .stdin(std::process::Stdio::null())
        .stdout(std::process::Stdio::piped())
        .stderr(std::process::Stdio::piped());
    let out = cmd
        .output()
        .await
        .map_err(|e| anyhow!("não foi possível iniciar o yt-dlp: {}", e))?;
    let text = String::from_utf8_lossy(&out.stdout);
    let line = text
        .lines()
        .map(|l| l.trim())
        .find(|l| l.starts_with('{'))
        .unwrap_or("");
    if line.is_empty() {
        let tail = String::from_utf8_lossy(&out.stderr).to_string();
        return Err(anyhow!("{}", short_reason(&tail)));
    }
    serde_json::from_str(line).map_err(|e| anyhow!("o JSON do yt-dlp não foi lido: {}", e))
}

// ───────────────────────── formatação ─────────────────────────

pub fn fmt_utc(ts: i64) -> String {
    chrono::DateTime::from_timestamp(ts, 0)
        .map(|d| d.format("%Y-%m-%d %H:%M UTC").to_string())
        .unwrap_or_default()
}

/// Escapa um campo de CSV do jeito que a planilha espera.
pub fn csv_escape(s: &str) -> String {
    if s.contains([',', '"', '\n', '\r']) {
        format!("\"{}\"", s.replace('"', "\"\""))
    } else {
        s.to_string()
    }
}

View on GitHub (pinned to 8600b91f42)