tonhowtf/omniget · error
cole o link de um VOD ou de um clipe da Twitch
Error message
cole o link de um VOD ou de um clipe da Twitch: {} What it means
resolve_chat_target parses a user-pasted string into a Twitch VOD or clip target. When parse_video cannot extract a video id or clip slug from the input, it throws this anyhow error embedding the original input. It is a user-input validation error, not an internal fault.
Solutions
- Check that the input matches a supported Twitch VOD URL pattern (twitch.tv/videos/<id>) or clip URL (twitch.tv/<ch>/clip/<slug> or clips.twitch.tv/<slug>) before calling
- Trim whitespace and strip query parameters (?t=...) from the pasted link
- Ask the user to re-copy the link directly from the VOD/clip share button
- If supporting more formats is desired, extend parse_video in gql.rs to handle them
Example fix
// before
let info = tool.resolve_chat_target("twitch.tv/somechannel").await?;
// after
let input = "twitch.tv/somechannel";
if !input.contains("/videos/") && !input.contains("/clip/") && !input.contains("clips.twitch.tv") {
anyhow::bail!("{} não é um link de VOD ou clipe da Twitch", input);
}
let info = tool.resolve_chat_target(input).await?; Defensive patterns
Strategy: validation
Validate before calling
fn is_twitch_vod_or_clip(input: &str) -> bool {
let u = input.trim();
u.contains("twitch.tv/videos/") || u.contains("/clip/") || u.contains("clips.twitch.tv/")
} Type guard
fn looks_like_twitch_url(s: &str) -> bool {
s.starts_with("https://") && (s.contains("twitch.tv/videos/") || s.contains("clips.twitch.tv"))
} Try / catch
match tool.resolve_chat_target(input).await {
Ok(info) => info,
Err(e) => { show_user("link inválido, use um VOD ou clipe da Twitch"); return; }
} Prevention
- Validate the pasted string against Twitch URL patterns before calling
- Strip query strings and whitespace from user input
- Show a clear UI hint of the accepted link formats
When it happens
Trigger: Calling resolve_chat_target with a string that is not a Twitch VOD/clip URL (e.g. a channel URL, a plain video id without context, a YouTube link, or arbitrary text).
Common situations: Users paste a channel page (twitch.tv/name) instead of a VOD link; paste a video ID alone like '123456789'; clipboard contains a timestamped or shortened link variant the parser does not handle.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Could not extract clip slug
- Track sem soundcloud_id
- SoundCloud nao retornou URL
- Spotify SDK device not ready
- Track sem metadata pra resolver no YouTube
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/870384aee73356a1.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/twitch/gql.rs:265
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> {
v.as_f64()
.or_else(|| v.as_str().and_then(|s| s.parse().ok()))
}
pub(super) fn str_at(v: &Value, key: &str) -> String {
v.get(key)
.and_then(|x| x.as_str())
.unwrap_or_default()
.to_string()
}View on GitHub (pinned to 8600b91f42)