{"record":{"id":"512d341d223baf7e","repo":"tonhowtf/omniget","slug":"esse-vod-n-o-devolveu-nenhuma-mensagem-de-chat","errorCode":null,"errorMessage":"esse VOD não devolveu nenhuma mensagem de chat","messagePattern":"esse VOD não devolveu nenhuma mensagem de chat","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/twitch/chat.rs","lineNumber":502,"sourceCode":"    let gql = Gql::new()?;\n    report(p, ID, \"progress\", 0, None, Some(\"lendo o VOD\".into()));\n    let info: VideoInfo = gql.resolve_chat_target(&opts.input).await?;\n\n    // Clipe: já limita o trecho à janela do clipe, com uma folga de 5 s.\n    let mut opts = opts.clone();\n    if let (Some(off), Some(dur)) = (info.clip_offset, info.clip_duration) {\n        if opts.start_seconds <= 0.0 {\n            opts.start_seconds = (off - 5.0).max(0.0);\n        }\n        if opts.end_seconds <= 0.0 {\n            opts.end_seconds = off + dur + 5.0;\n        }\n    }\n\n    let (messages, pages, offset_fallback) =\n        fetch_all(&gql, &info.id, &opts, info.duration_seconds, p).await?;\n    if messages.is_empty() {\n        bail!(\"esse VOD não devolveu nenhuma mensagem de chat\");\n    }\n\n    let formats: Vec<String> = if opts.formats.is_empty() {\n        vec![\"json\".into(), \"csv\".into()]\n    } else {\n        opts.formats.iter().map(|f| f.to_lowercase()).collect()\n    };\n\n    let series = peaks(&messages, 60.0);\n    let mut top_peaks = series.clone();\n    top_peaks.sort_by_key(|p| std::cmp::Reverse(p.count));\n    top_peaks.truncate(10);\n\n    let dir = PathBuf::from(&opts.out_dir);\n    std::fs::create_dir_all(&dir)?;\n    let stem = sanitize_name(&format!(\n        \"{}-{}-chat\",\n        if info.channel.is_empty() {","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/twitch/chat.rs#L484-L520","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the VOD id is a valid Twitch VOD id and that the VOD still exists and is public (open its URL).","Widen the time window / start-offset options so the request covers a range where chat messages exist.","If the VOD is subscriber-only, authenticate so GQL can access the chat replay.","If the chat is genuinely empty and you still want output, handle this error upstream and skip or write an empty export yourself."],"exampleFix":"// before\nchat::export(&opts).await?; // bails: \"esse VOD não devolveu nenhuma mensagem de chat\"\n\n// after\nmatch chat::export(&opts).await {\n    Ok(files) => println!(\"exportado: {:?}\", files),\n    Err(e) if e.to_string().contains(\"nenhuma mensagem de chat\") => {\n        eprintln!(\"VOD {} não tem chat para exportar; pulando\", opts.vod_id);\n    }\n    Err(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":"let vod_url = format!(\"https://www.twitch.tv/videos/{}\", opts.vod_id);\n// confirm the VOD exists and is public (or authenticated) before exporting:\n// if the video page 404s or requires sub, expect this error\nif opts.start_seconds >= opts.duration_seconds {\n    return Err(anyhow!(\"janela de exportação fora do VOD\"));\n}","typeGuard":null,"tryCatchPattern":"match chat::export(&opts).await {\n    Err(e) if e.to_string().contains(\"nenhuma mensagem de chat\") => eprintln!(\"sem chat para este VOD; pulando\"),\n    other => other?,\n}","preventionTips":["Validate VOD ids against the video page before exporting.","Ensure the time window overlaps actual broadcast duration.","Authenticate when exporting subscriber-only VODs.","Match on the specific message to distinguish empty-chat from other export failures."],"tags":["twitch","chat","empty-result","vod-export"],"backgroundTag":"empty-result-set","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"}