tonhowtf/omniget · error · anyhow::Error

Could not extract clip slug

Error message

Could not extract clip slug

What it means

native_get_media_info for Twitch derives the clip identity from the URL via extract_clip_slug(), which parses the slug out of a clips.twitch.com/.../Slug or twitch.tv/clip/Slug style URL. This error is thrown when the URL does not match any recognized clip URL pattern, so no slug can be obtained to query the Twitch GQL clip metadata API.

Solutions

  1. Confirm the URL is a clip link of the form clips.twitch.tv/<channel>/<slug> or twitch.tv/<channel>/clip/<slug>.
  2. Strip query parameters and trailing slashes before passing the URL.
  3. Update extract_clip_slug to handle additional Twitch URL formats if a new shape appears.
  4. Let the request fall through to the generic yt-dlp path, which handles more Twitch URL types.

Example fix

// before
let slug = Self::extract_clip_slug(url)
    .ok_or_else(|| anyhow!("Could not extract clip slug"))?;
// after
let slug = Self::extract_clip_slug(url).ok_or_else(|| anyhow!(
    "Could not extract clip slug from '{}' — expected a clips.twitch.tv/<channel>/<slug> URL",
    url
))?;
Defensive patterns

Strategy: validation

Validate before calling

// Validate the URL shape before calling get_media_info
let is_clip = url.contains("clips.twitch.tv") || url.contains("/clip/");
if !is_clip { eprintln!("not a Twitch clip URL"); }

Type guard

fn looks_like_clip_url(url: &str) -> bool {
    url.contains("clips.twitch.tv/") || url.contains("/clip/")
}

Try / catch

match get_media_info(url).await {
    Err(e) if e.to_string().contains("clip slug") => try_generic_ytdlp(url).await,
    other => other,
}

Prevention

When it happens

Trigger: Calling get_media_info on a Twitch URL that is not a clip URL (a VOD, channel, or homepage URL), or a malformed clip URL (missing slug, extra segments, mobile subdomain variant not covered by the regex).

Common situations: Users pasting a VOD link (videos.twitch.tv) expecting clip download; clip links with trailing query strings or locale prefixes; new Twitch clip URL formats not matching the extractor.

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/d057c124037d2261. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/platforms/twitch/mod.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)