tonhowtf/omniget · error

esse VOD não devolveu nenhuma mensagem de chat

Error message

esse VOD não devolveu nenhuma mensagem de chat

What it means

export() in twitch/chat.rs fails when fetch_all() returns zero chat messages for the requested VOD. The library bails early instead of writing empty export files, because a chat download with no messages is almost always a symptom of a bad VOD id, a deleted/ballchking VOD, or an unauthorized (subscriber-only) VOD rather than a genuinely empty chat.

Solutions

  1. Verify the VOD id is a valid Twitch VOD id and that the VOD still exists and is public (open its URL).
  2. Widen the time window / start-offset options so the request covers a range where chat messages exist.
  3. If the VOD is subscriber-only, authenticate so GQL can access the chat replay.
  4. If the chat is genuinely empty and you still want output, handle this error upstream and skip or write an empty export yourself.

Example fix

// before
chat::export(&opts).await?; // bails: "esse VOD não devolveu nenhuma mensagem de chat"

// after
match chat::export(&opts).await {
    Ok(files) => println!("exportado: {:?}", files),
    Err(e) if e.to_string().contains("nenhuma mensagem de chat") => {
        eprintln!("VOD {} não tem chat para exportar; pulando", opts.vod_id);
    }
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: try-catch

Validate before calling

let vod_url = format!("https://www.twitch.tv/videos/{}", opts.vod_id);
// confirm the VOD exists and is public (or authenticated) before exporting:
// if the video page 404s or requires sub, expect this error
if opts.start_seconds >= opts.duration_seconds {
    return Err(anyhow!("janela de exportação fora do VOD"));
}

Try / catch

match chat::export(&opts).await {
    Err(e) if e.to_string().contains("nenhuma mensagem de chat") => eprintln!("sem chat para este VOD; pulando"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling export() (directly or via live_exporta_um_trecho) when: the VOD id is wrong/typo'd, the VOD was deleted or made sub-only so GQL returns valid metadata but no chat replay pages, the requested time window/duration yields no pages, or the GQL chat endpoint silently returns an empty message list.

Common situations: Exporting a subscriber-only VOD's chat without auth; exporting a very short clip window where no chat lines were sent; passing a clip id instead of a VOD id; Twitch removing chat replay for old VODs.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/twitch/chat.rs:502

    let gql = Gql::new()?;
    report(p, ID, "progress", 0, None, Some("lendo o VOD".into()));
    let info: VideoInfo = gql.resolve_chat_target(&opts.input).await?;

    // Clipe: já limita o trecho à janela do clipe, com uma folga de 5 s.
    let mut opts = opts.clone();
    if let (Some(off), Some(dur)) = (info.clip_offset, info.clip_duration) {
        if opts.start_seconds <= 0.0 {
            opts.start_seconds = (off - 5.0).max(0.0);
        }
        if opts.end_seconds <= 0.0 {
            opts.end_seconds = off + dur + 5.0;
        }
    }

    let (messages, pages, offset_fallback) =
        fetch_all(&gql, &info.id, &opts, info.duration_seconds, p).await?;
    if messages.is_empty() {
        bail!("esse VOD não devolveu nenhuma mensagem de chat");
    }

    let formats: Vec<String> = if opts.formats.is_empty() {
        vec!["json".into(), "csv".into()]
    } else {
        opts.formats.iter().map(|f| f.to_lowercase()).collect()
    };

    let series = peaks(&messages, 60.0);
    let mut top_peaks = series.clone();
    top_peaks.sort_by_key(|p| std::cmp::Reverse(p.count));
    top_peaks.truncate(10);

    let dir = PathBuf::from(&opts.out_dir);
    std::fs::create_dir_all(&dir)?;
    let stem = sanitize_name(&format!(
        "{}-{}-chat",
        if info.channel.is_empty() {

View on GitHub (pinned to 8600b91f42)