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
- Re-fetch MediaInfo via `get_media_info` immediately before downloading so URLs are fresh.
- Log in / select the right account (`active_account_slug`) so protected streams resolve.
- Inspect the parsed response: if the API returned no stream URLs, the content likely requires purchase/login or is unavailable.
- 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
- Re-fetch MediaInfo right before download; URLs expire.
- Ensure the correct account is active for protected content.
- Validate parsed results so empty stream lists surface early.
- Handle login/charge-only content explicitly instead of passing empty qualities through.
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
- No URL available
- All playlist item(s) failed to download. First error
- No URL available
- Failed to parse content
- No URL available
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)