tonhowtf/omniget · error · anyhow::Error

No URL available

Error message

No URL available

What it means

The modern API-engine download path (`api_engine_download`) mirrors the legacy check: it takes the first entry of `info.available_qualities` and throws `No URL available` when the resolved URL is empty. The API engine cannot build an effective download URL without one.

Solutions

  1. Re-fetch MediaInfo via `get_media_info` immediately before downloading so URLs are fresh.
  2. Log in / select the right account (`active_account_slug`) so protected streams resolve.
  3. Inspect the parsed response: if the API returned no stream URLs, the content likely requires purchase/login or is unavailable.
  4. Check `info.available_qualities` non-empty before calling download and surface a friendly message.

Example fix

// before
download(info, opts, progress).await?; // No URL available
// after
ensure!(!info.available_qualities.is_empty() && !info.available_qualities[0].url.is_empty(), "no stream");
let info = get_media_info(&source_url).await?; // refresh
download(info, opts, progress).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn stream_url_ready(info: &MediaInfo) -> bool {
    info.available_qualities.first().map(|q| !q.url.is_empty()).unwrap_or(false)
}
if !stream_url_ready(&info) { info = get_media_info(&src).await?; }

Try / catch

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

Prevention

When it happens

Trigger: Calling `download` routed to the API engine with a MediaInfo whose `available_qualities` is empty or whose first quality has an empty `url` — failed parse, expired stream URLs, or content (e.g. charge-only/region-locked videos) that yields no playable streams for the current account.

Common situations: Downloading premium (充电专属) or region-locked Bilibili videos without proper login/account; stale MediaInfo fetched long before download; API returning metadata but empty `durl`/`dash` lists; bug in a parser producing quality entries with empty URLs.

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

Appendix: source

Thrown at src-tauri/src/platforms/bilibili/mod.rs:108

        }
        line.split('\t').nth(5) == Some("SESSDATA")
    })
}

async fn api_engine_download(
    info: &MediaInfo,
    opts: &DownloadOptions,
    progress: mpsc::Sender<ProgressUpdate>,
) -> anyhow::Result<DownloadResult> {
    let _ = cookie::ensure_fresh().await;

    let url = info
        .available_qualities
        .first()
        .map(|q| q.url.as_str())
        .unwrap_or("");
    if url.is_empty() {
        return Err(anyhow!("No URL available"));
    }

    let slug = active_account_slug();
    let client = build_api_client(slug.as_deref(), opts.user_agent.as_deref())?;

    let mut effective_url = url.to_string();
    if url_kind::is_b23_short(&effective_url) {
        if let Ok(resolved) = url_kind::resolve_b23(&client, &effective_url).await {
            effective_url = resolved;
        }
    }

    let kind = url_kind::detect(&effective_url)
        .map_err(|e| anyhow!("Failed to detect URL kind: {}", e.i18n_key()))?;
    let parsed = parser::parse(&client, &kind)
        .await
        .map_err(|e| anyhow!("Failed to parse content: {}", e.i18n_key()))?;

View on GitHub (pinned to 8600b91f42)