tonhowtf/omniget · error · anyhow::Error
{}
Error message
{} What it means
After running yt-dlp in JSON mode, `ytdlp_json` scans stdout for a line starting with '{'. If none is found, it treats the run as failed and raises an error whose message is the shortened stderr reason (via `short_reason`). This surfaces yt-dlp's own failure output (e.g. video unavailable, login required) as the error.
Solutions
- Read the `{}` message: it is the shortened stderr from yt-dlp; fix the cause it names (URL, login, network).
- Update yt-dlp to the latest version (`yt-dlp -U` or pip install -U yt-dlp) — TikTok extractors change often.
- Verify the video URL opens in a browser and is public.
- If cookies/session are required, pass the session cookie file to yt-dlp.
Example fix
// before $ yt-dlp -j https://www.tiktok.com/@u/video/123 ERROR: video unavailable // after $ yt-dlp -U # update extractors, then retry with a valid public URL
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the URL shape before invoking yt-dlp
if !url.contains("tiktok.com") { return Err(anyhow!("URL não parece ser do TikTok")); } Try / catch
match ytdlp_json(&args).await {
Ok(v) => Ok(v),
Err(e) if e.to_string().contains("unavailable") => warn_user_and_skip(),
Err(e) => { update_ytdlp().await; Err(e) },
} Prevention
- Keep yt-dlp updated — TikTok extractors break frequently.
- Check that the target video is public and reachable before downloading.
- Surface the shortened yt-dlp stderr reason to the end user for actionable feedback.
When it happens
Trigger: yt-dlp exits with no JSON on stdout — unsupported/removed video, network failure, age/login restriction, bad URL, or a yt-dlp version whose output format changed; stdout is empty while stderr carries the reason.
Common situations: Private or region-blocked TikTok video; yt-dlp outdated for a changed TikTok page structure; bot-check/captcha page returned instead of media; invalid or malformed URL passed in.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/7639d8e3d53e37c5.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/tiktok/mod.rs:757
let bin = ytdlp_binary().await?;
let mut cmd = crate::core::ytdlp::ytdlp_command(&bin);
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)