tonhowtf/omniget · error
esse clipe não tem VOD de origem, então não há chat
Error message
esse clipe não tem VOD de origem, então não há chat
What it means
clip_video() throws this when the clip exists but its video.id pointer is absent, i.e. the clip has no source VOD. Chat replay is stored on the VOD, so without a source video there is no chat to download for a clip. The library refuses rather than returning a video-less result.
Solutions
- Accept that clip chat is unavailable and download the chat of an available VOD instead
- Locate another clip of the same stream whose source VOD still exists
- If the channel reuploaded/saved the stream, resolve the VOD id and use video()/fetch_all directly
- Handle this error distinctly from 'clip not found' in caller UX
Example fix
// before
let target = resolve_chat_target(&arg).await?; // may be a sourceless clip
// after
let target = match resolve_chat_target(&arg).await {
Ok(t) => t,
Err(e) if e.to_string().contains("não tem VOD de origem") => {
eprintln!("clip has no source VOD; no chat replay exists");
return Err(e);
}
Err(e) => return Err(e),
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Not checkable pre-call via this API; the clip's source-VOD link is only in the response.
Try / catch
match gql.clip_video(slug).await {
Err(e) if e.to_string().contains("não tem VOD de origem") => {
eprintln!("Clip exists but its source stream has no saved VOD — no chat replay");
Ok(())
}
other => other,
} Prevention
- Prefer resolving chat from the original VOD when you know its id
- Don't assume every clip has a downloadable chat replay
- Handle this distinctly from clip-not-found in UX messaging
- Check the clip's page — it will show 'source video unavailable' when this applies
When it happens
Trigger: Calling gql.clip_video(slug) (or resolve_chat_target with a clip) for a clip whose source broadcast was deleted or expired after the clip was created, or clips made in contexts without an attached VOD.
Common situations: Old clips whose source stream was never saved or later deleted/expired; clips on channels that never keep VODs; asking for chat download on such a clip instead of the original stream's VOD.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- resposta sem comentários (o VOD tem replay de chat?)
- VOD não encontrado (ou já expirou)
- clipe não encontrado
- resposta do Twitch GQL sem `data`
- resposta em lote inesperada do Twitch GQL
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/4f13772fb33c42b5.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/twitch/gql.rs:255
created_at: str_at(v, "createdAt"),
clip_offset: None,
clip_duration: None,
})
}
/// Clipe → VOD de origem, com a janela do clipe dentro dele.
pub async fn clip_video(&self, slug: &str) -> anyhow::Result<VideoInfo> {
let q = format!(
r#"{{ clip(slug: "{}") {{ durationSeconds videoOffsetSeconds video {{ id }} }} }}"#,
escape(slug)
);
let data = self.query(&q).await?;
let c = data.get("clip").filter(|v| !v.is_null());
let c = c.ok_or_else(|| anyhow!("clipe não encontrado: {}", slug))?;
let vid = c
.pointer("/video/id")
.and_then(|x| x.as_str())
.ok_or_else(|| anyhow!("esse clipe não tem VOD de origem, então não há chat"))?;
let mut info = self.video(vid).await?;
info.clip_offset = c.get("videoOffsetSeconds").and_then(num);
info.clip_duration = c.get("durationSeconds").and_then(num);
Ok(info)
}
/// Resolve o que o usuário colou até chegar num VOD.
pub async fn resolve_chat_target(&self, input: &str) -> anyhow::Result<VideoInfo> {
let target = parse_video(input)
.ok_or_else(|| anyhow!("cole o link de um VOD ou de um clipe da Twitch: {}", input))?;
match target {
ChatTarget::Video(id) => self.video(&id).await,
ChatTarget::Clip(slug) => self.clip_video(&slug).await,
}
}
}
fn num(v: &Value) -> Option<f64> {View on GitHub (pinned to 8600b91f42)