tonhowtf/omniget · error

Could not extract clip slug

Error message

Could not extract clip slug

What it means

Raised by TwitchClipsDownloader::native_get_media_info when extract_clip_slug(url) returns None, i.e. the URL could not be parsed as a Twitch clip link (neither clips.twitch.tv/<slug> nor twitch.tv/<channel>/clip/<slug>).

Solutions

  1. Validate the URL matches clips.twitch.tv/<slug> or twitch.tv/<channel>/clip/<slug> before calling
  2. Ensure the URL is percent-decoded and free of tracking query parameters
  3. Use the yt-dlp fallback path for non-clip Twitch URLs

Example fix

// before
let slug = Self::extract_clip_slug(url).ok_or_else(|| anyhow!("Could not extract clip slug"))?;
// after
let Some(slug) = Self::extract_clip_slug(url) else {
    return self.fallback_ytdlp(url).await;
};
Defensive patterns

Strategy: validation

Validate before calling

const CLIP_RE: &str = r"^(https?://)?(www\.)?(clips\.twitch\.tv/[\w-]+|twitch\.tv/[\w-]+/clip/[\w-]+)";
let ok = regex::Regex::new(CLIP_RE).unwrap().is_match(url);

Type guard

fn is_twitch_clip_url(url: &str) -> bool {
    url::Url::parse(url).ok()
        .and_then(|u| u.host_str().map(|h| h.to_lowercase()))
        .map(|h| h.ends_with("twitch.tv"))
        .unwrap_or(false)
        && (url.contains("clips.twitch.tv") || url.contains("/clip/"))
}

Try / catch

match downloader.get_media_info(url).await {
    Err(e) if e.to_string().contains("Could not extract clip slug") => {
        Err(anyhow::anyhow!("'{url}' is not a Twitch clip URL (expected clips.twitch.tv/<slug> or twitch.tv/<channel>/clip/<slug>)"))
    }
    other => other,
}

Prevention

When it happens

Trigger: Passing a URL that is a full Twitch VOD, channel page, or a malformed/non-Twitch URL to get_media_info for a Twitch clip; e.g. https://twitch.tv/channel (no /clip segment) or a URL with query-embedding edge cases.

Common situations: Users paste a VOD or channel URL expecting clip download; a frontend passes an already-unwrapped player URL or a localized redirect URL the parser doesn't recognize.

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


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

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/twitch.rs:51

    client: reqwest::Client,
}

impl Default for TwitchClipsDownloader {
    fn default() -> Self {
        Self::new()
    }
}

impl TwitchClipsDownloader {
    async fn fallback_ytdlp(&self, url: &str) -> anyhow::Result<MediaInfo> {
        let ytdlp_path = crate::core::ytdlp::ensure_ytdlp().await?;
        let json = crate::core::ytdlp::get_video_info(&ytdlp_path, url, &[]).await?;
        crate::platforms::generic_ytdlp::GenericYtdlpDownloader::parse_video_info(&json)
    }

    async fn native_get_media_info(&self, url: &str) -> anyhow::Result<MediaInfo> {
        let slug =
            Self::extract_clip_slug(url).ok_or_else(|| anyhow!("Could not extract clip slug"))?;

        let clip = self.fetch_clip_metadata(&slug).await?;

        if clip.video_qualities.is_empty() {
            return Err(anyhow!("No video quality available"));
        }

        let broadcaster = clip
            .broadcaster_login
            .as_deref()
            .ok_or_else(|| anyhow!("Dados do clip incompletos"))?;

        let token = self.fetch_access_token(&slug).await?;

        let clip_title = clip.title.trim().to_string();

        let available_qualities: Vec<VideoQuality> = clip
            .video_qualities

View on GitHub (pinned to 8600b91f42)