tonhowtf/omniget · error

No URL available

Error message

No URL available

What it means

Thrown in DirectFileDownloader::download when no usable URL can be derived: either available_qualities is empty, or the first entry's URL is an empty string (the .filter(|u| !u.is_empty()) drops it). The downloader has nothing to fetch.

Solutions

  1. Ensure available_qualities contains an entry with a non-empty url before calling download().
  2. Re-run the page scrape / get_media_info to recover the direct URL.
  3. Check the source URL actually points to a downloadable file (not an HTML page).
  4. Validate MediaInfo in the caller and show a user-facing 'no downloadable URL' message.

Example fix

// before
let info = MediaInfo { available_qualities: vec![VideoQuality { url: String::new(), .. }], .. };
downloader.download(&info, &opts, tx).await?;
// after
if info.available_qualities.first().map_or(true, |q| q.url.is_empty()) {
    return Err(anyhow!("refusing to download: no direct file URL resolved"));
}
Defensive patterns

Strategy: validation

Validate before calling

let has_url = info.available_qualities.first().map_or(false, |q| !q.url.is_empty());
if !has_url {
    return Err(anyhow!("no direct file URL; re-scrape the source page"));
}

Type guard

fn has_direct_url(info: &MediaInfo) -> bool {
    info.available_qualities.first().map_or(false, |q| !q.url.is_empty())
}

Try / catch

match downloader.download(&info, &opts, tx).await {
    Err(e) if e.to_string() == "No URL available" => {
        eprintln!("source page exposed no direct file URL; check the link");
    }
    other => other,
}

Prevention

When it happens

Trigger: download() called with a MediaInfo whose available_qualities is empty, or whose first quality URL is "" (e.g. metadata was parsed from a page with no direct file link).

Common situations: Direct-file entries built from pages that failed to expose a media URL, partially populated MediaInfo structs, or callers stripping qualities before handing them to the downloader.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/direct_file.rs:219

            media_type: MediaType::File,
            file_size_bytes,
        })
    }

    async fn download(
        &self,
        info: &MediaInfo,
        opts: &DownloadOptions,
        progress: mpsc::Sender<ProgressUpdate>,
    ) -> anyhow::Result<DownloadResult> {
        let _ = progress.send(ProgressUpdate::percent(0.0)).await;

        let file_url = info
            .available_qualities
            .first()
            .map(|q| q.url.as_str())
            .filter(|u| !u.is_empty())
            .ok_or_else(|| anyhow!("No URL available"))?;

        let filename = sanitize_filename::sanitize(&info.title);
        let filename = if filename.is_empty() {
            filename_from_url(file_url)
        } else {
            filename
        };
        let output_path = opts.output_dir.join(&filename);

        let mut builder = http_client::apply_global_proxy(reqwest::Client::builder())
            .connect_timeout(std::time::Duration::from_secs(30));

        if let Some(ua) = opts.user_agent.as_deref() {
            builder = builder.user_agent(ua);
        }

        let jar =
            crate::core::cookie_parser::load_extension_cookies_for_url(file_url).or_else(|| {

View on GitHub (pinned to 8600b91f42)