tonhowtf/omniget · error

Twitch recusou o replay de chat

Error message

Twitch recusou o replay de chat: {}

What it means

The Twitch chat replay fetcher pages through chat history via the Twitch API. When the API responds with an error, the tool retries with a cursor-less offset fallback; if the failure persists (or is not the fallback-eligible case), it bails with Twitch's own error message interpolated into this message.

Solutions

  1. Check that the video/VOD ID is valid and the VOD still exists with chat replay available
  2. Retry later if the message indicates rate limiting or a Twitch-side error (429/5xx)
  3. Confirm the VOD is within Twitch's chat retention window (chat expires ~14 days for most, shorter for subs-only mode)
  4. Verify network access / API tokens used by the underlying client
  5. Inspect the interpolated `msg` in the error to identify Twitch's exact complaint

Example fix

// before
export(&ExportOptions { video_id: "deleted_vod_id".into(), .. }).await?;
// after
let id = "valid_vod_id";
if twitch_vod_exists(id) && twitch_chat_available(id) {
    export(&ExportOptions { video_id: id.into(), .. }).await?;
}
Defensive patterns

Strategy: retry

Validate before calling

// validate VOD/chat availability before export
if !twitch_chat_replay_available(&video_id).await {
    return Err(anyhow!("replay de chat indisponível para {}", video_id));
}

Try / catch

match export(opts).await {
    Err(e) if e.to_string().contains("Twitch recusou o replay de chat") => {
        if is_rate_limit(&e) { tokio::time::sleep(BACKOFF).await; retry() }
        else { eprintln!("VOD inválido/expirado ou Twitch fora do ar: {}", e); }
    }
    Err(e) => return Err(e),
    Ok(r) => use(r),
}

Prevention

When it happens

Trigger: Calling export/fetch_all when the Twitch chat-replay endpoint returns an error — invalid video/VOD ID, VOD too old or deleted (sub-only chat expiration), rate limiting, or Twitch API outage — and it is not recoverable by the offset fallback.

Common situations: Using a video ID for a live stream with no replay yet; a VOD older than the chat retention window; expired/deleted VOD; transient 5xx or 429 responses; network blocking Twitch API access.

Related errors


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

Appendix: source

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

    report(p, ID, "started", 0, total, None);
    loop {
        let vars = match (use_cursor, cursor.as_ref()) {
            (true, Some(c)) => json!({ "videoID": video_id, "cursor": c }),
            _ => json!({ "videoID": video_id, "contentOffsetSeconds": offset }),
        };
        let raw = gql.persisted(OP, COMMENTS_HASH, vars).await?;
        if let Some(msg) = first_error(&raw) {
            let integrity = msg.to_lowercase().contains("integrity");
            if integrity && use_cursor {
                // A Twitch fechou o cursor para cliente anônimo: segue por
                // offset, deduplicando pelas mensagens que já vieram.
                use_cursor = false;
                offset_fallback = true;
                cursor = None;
                continue;
            }
            bail!("Twitch recusou o replay de chat: {}", msg);
        }
        let page = parse_page(&raw)?;
        pages += 1;
        if page.messages.is_empty() {
            break;
        }

        let last_offset = page
            .messages
            .iter()
            .map(|m| m.offset)
            .fold(offset, f64::max);
        let mut fresh = 0usize;
        for m in page.messages {
            if m.offset < start || m.offset > end {
                continue;
            }
            if seen.insert(m.id.clone()) {

View on GitHub (pinned to 8600b91f42)