tonhowtf/omniget · error

clipe não encontrado

Error message

clipe não encontrado: {}

What it means

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.

Solutions

  1. Verify the clip opens at its URL on twitch.tv
  2. Extract only the slug from the clip URL (the path segment after /clip/ or the last segment)
  3. Try a different clip; deleted clips cannot be resolved
  4. Check for whitespace/newlines accidentally included in the slug

Example fix

// before
let info = gql.clip_video("https://clips.twitch.tv/SomeClip-Abc").await?;
// after
let info = gql.clip_video("SomeClip-Abc").await?;
Defensive patterns

Strategy: validation

Validate before calling

fn extract_slug(url_or_slug: &str) -> Option<&str> {
    let s = url_or_slug.trim();
    if let Some(rest) = s.strip_prefix("https://clips.twitch.tv/") {
        return rest.split(&['/', '?'][..]).next();
    }
    if let Some(idx) = s.find("/clip/") {
        return s[idx + 6..].split(&['/', '?'][..]).next();
    }
    (!s.is_empty() && !s.chars().all(|c| c.is_ascii_digit())).then_some(s)
}

Try / catch

match gql.clip_video(slug).await {
    Err(e) if e.to_string().contains("clipe não encontrado") => {
        eprintln!("Clip '{slug}' not found or deleted");
        Ok(())
    }
    other => other,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/twitch/gql.rs:251

                .and_then(|x| x.as_str())
                .unwrap_or_default()
                .to_string(),
            duration_seconds: v.get("lengthSeconds").and_then(num).unwrap_or_default(),
            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,
        }

View on GitHub (pinned to 8600b91f42)