{"record":{"id":"adc8af46b977edbf","repo":"tonhowtf/omniget","slug":"clipe-n-o-encontrado","errorCode":null,"errorMessage":"clipe não encontrado: {}","messagePattern":"clipe não encontrado: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/twitch/gql.rs","lineNumber":251,"sourceCode":"                .and_then(|x| x.as_str())\n                .unwrap_or_default()\n                .to_string(),\n            duration_seconds: v.get(\"lengthSeconds\").and_then(num).unwrap_or_default(),\n            created_at: str_at(v, \"createdAt\"),\n            clip_offset: None,\n            clip_duration: None,\n        })\n    }\n\n    /// Clipe → VOD de origem, com a janela do clipe dentro dele.\n    pub async fn clip_video(&self, slug: &str) -> anyhow::Result<VideoInfo> {\n        let q = format!(\n            r#\"{{ clip(slug: \"{}\") {{ durationSeconds videoOffsetSeconds video {{ id }} }} }}\"#,\n            escape(slug)\n        );\n        let data = self.query(&q).await?;\n        let c = data.get(\"clip\").filter(|v| !v.is_null());\n        let c = c.ok_or_else(|| anyhow!(\"clipe não encontrado: {}\", slug))?;\n        let vid = c\n            .pointer(\"/video/id\")\n            .and_then(|x| x.as_str())\n            .ok_or_else(|| anyhow!(\"esse clipe não tem VOD de origem, então não há chat\"))?;\n        let mut info = self.video(vid).await?;\n        info.clip_offset = c.get(\"videoOffsetSeconds\").and_then(num);\n        info.clip_duration = c.get(\"durationSeconds\").and_then(num);\n        Ok(info)\n    }\n\n    /// Resolve o que o usuário colou até chegar num VOD.\n    pub async fn resolve_chat_target(&self, input: &str) -> anyhow::Result<VideoInfo> {\n        let target = parse_video(input)\n            .ok_or_else(|| anyhow!(\"cole o link de um VOD ou de um clipe da Twitch: {}\", input))?;\n        match target {\n            ChatTarget::Video(id) => self.video(&id).await,\n            ChatTarget::Clip(slug) => self.clip_video(&slug).await,\n        }","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/twitch/gql.rs#L233-L269","documentation":"clip_video() resolves a clip slug to its source VOD and throws when the GraphQL clip lookup returns clip:null, meaning no clip exists with that slug. This is a not-found guard distinct from the later check that the clip has a source video.","triggerScenarios":"Calling gql.clip_video(slug) (directly or via resolve_chat_target) with an invalid, deleted, or mistyped clip slug — e.g. pasting the full share URL when the parser expected just the slug, or a clip removed by its creator.","commonSituations":"Clips deleted or expired; typos when hand-copying slugs; passing a video id or VOD URL where a clip slug is expected; regional/blocked clips; clip from a deactivated channel.","solutions":["Verify the clip opens at its URL on twitch.tv","Extract only the slug from the clip URL (the path segment after /clip/ or the last segment)","Try a different clip; deleted clips cannot be resolved","Check for whitespace/newlines accidentally included in the slug"],"exampleFix":"// before\nlet info = gql.clip_video(\"https://clips.twitch.tv/SomeClip-Abc\").await?;\n// after\nlet info = gql.clip_video(\"SomeClip-Abc\").await?;","handlingStrategy":"validation","validationCode":"fn extract_slug(url_or_slug: &str) -> Option<&str> {\n    let s = url_or_slug.trim();\n    if let Some(rest) = s.strip_prefix(\"https://clips.twitch.tv/\") {\n        return rest.split(&['/', '?'][..]).next();\n    }\n    if let Some(idx) = s.find(\"/clip/\") {\n        return s[idx + 6..].split(&['/', '?'][..]).next();\n    }\n    (!s.is_empty() && !s.chars().all(|c| c.is_ascii_digit())).then_some(s)\n}","typeGuard":null,"tryCatchPattern":"match gql.clip_video(slug).await {\n    Err(e) if e.to_string().contains(\"clipe não encontrado\") => {\n        eprintln!(\"Clip '{slug}' not found or deleted\");\n        Ok(())\n    }\n    other => other,\n}","preventionTips":["Pass just the slug, not the full URL (or strip it first)","Verify the clip still opens on twitch.tv before resolving","Remember clips get deleted/expired — they are not permanent","Avoid whitespace/newlines when copying slugs from scripts"],"tags":["twitch","gql","clip","not-found"],"backgroundTag":"entity-not-found","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"}