tonhowtf/omniget · error

No URL available

Error message

No URL available

What it means

`download` takes the first entry of `info.available_qualities` and treats its `url` as the media stream; if the qualities list is empty or the first quality's URL is an empty string it throws `No URL available`. This protects against launching yt-dlp with a blank target.

Solutions

  1. Check `info.available_qualities` is non-empty and the first URL is non-blank before calling download.
  2. Re-run `get_media_info` to refresh stream URLs — they can expire and extraction may have failed silently.
  3. Ensure the user is logged in / cookies are configured when streams require authentication.
  4. Pick a specific quality explicitly rather than relying on `.first()` defaults.

Example fix

// before
download(info, opts, progress).await?; // panics if qualities empty
// after
if info.available_qualities.first().map(|q| q.url.is_empty()).unwrap_or(true) {
    info = get_media_info(&source_url).await?;
}
download(info, opts, progress).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn has_stream(info: &MediaInfo) -> bool {
    info.available_qualities.first().map(|q| !q.url.is_empty()).unwrap_or(false)
}

Try / catch

match download(info, opts, progress).await {
    Err(e) if e.to_string().contains("No URL available") => refresh_info_and_retry().await?,
    Err(e) => return Err(e),
    Ok(_) => {},
}

Prevention

When it happens

Trigger: Passing a MediaInfo produced by a failed/incomplete `get_media_info` call where `available_qualities` is empty, or where quality entries were built with empty `url` fields (e.g. extraction returned metadata but no stream URLs, or a hand-constructed MediaInfo).

Common situations: Chaining get_media_info → download without checking that qualities were populated; Bilibili returning metadata but stream extraction blocked (login/region); constructing MediaInfo manually in tests/fixtures with placeholder qualities.

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

Appendix: source

Thrown at src-tauri/src/platforms/bilibili/legacy.rs:184

    progress: mpsc::Sender<ProgressUpdate>,
) -> anyhow::Result<DownloadResult> {
    let _ = progress.send(ProgressUpdate::percent(0.0)).await;

    let ytdlp_path = match &opts.ytdlp_path {
        Some(p) => p.clone(),
        None => ytdlp::find_ytdlp_cached()
            .await
            .ok_or_else(|| anyhow!("yt-dlp not found"))?,
    };

    let url = info
        .available_qualities
        .first()
        .map(|q| q.url.as_str())
        .unwrap_or("");

    if url.is_empty() {
        return Err(anyhow!("No URL available"));
    }

    if info.media_type == MediaType::Playlist {
        return download_playlist(info, opts, progress, &ytdlp_path).await;
    }

    let quality_height = opts
        .quality
        .as_ref()
        .and_then(|q| q.trim_end_matches('p').parse::<u32>().ok());

    let extra = vec!["--no-playlist".to_string()];

    ytdlp::download_video(
        &ytdlp_path,
        url,
        &opts.output_dir,
        quality_height,

View on GitHub (pinned to 8600b91f42)