{"record":{"id":"789b427d608059e0","repo":"tonhowtf/omniget","slug":"no-url-available-mod","errorCode":null,"errorMessage":"No URL available","messagePattern":"No URL available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/bilibili/mod.rs","lineNumber":230,"sourceCode":"        }\n        line.split('\\t').nth(5) == Some(\"SESSDATA\")\n    })\n}\n\nasync fn api_engine_download(\n    info: &MediaInfo,\n    opts: &DownloadOptions,\n    progress: mpsc::Sender<ProgressUpdate>,\n) -> anyhow::Result<DownloadResult> {\n    let _ = cookie::ensure_fresh().await;\n\n    let url = info\n        .available_qualities\n        .first()\n        .map(|q| q.url.as_str())\n        .unwrap_or(\"\");\n    if url.is_empty() {\n        return Err(anyhow!(\"No URL available\"));\n    }\n\n    let slug = active_account_slug();\n    let client = build_api_client(slug.as_deref(), opts.user_agent.as_deref())?;\n\n    let mut effective_url = url.to_string();\n    if url_kind::is_b23_short(&effective_url) {\n        if let Ok(resolved) = url_kind::resolve_b23(&client, &effective_url).await {\n            effective_url = resolved;\n        }\n    }\n\n    let kind = url_kind::detect(&effective_url)\n        .map_err(|e| anyhow!(\"Failed to detect URL kind: {}\", e.i18n_key()))?;\n    let parsed = parser::parse(&client, &kind)\n        .await\n        .map_err(|e| anyhow!(\"Failed to parse content: {}\", e.i18n_key()))?;\n","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/bilibili/mod.rs#L212-L248","documentation":"api_engine_download() (the modern bilibili API path) takes the first URL from info.available_qualities, defaulting to \"\" when absent, and errors immediately if it is empty. Like the legacy path, this signals that parsing produced no usable stream URL, so the download engine cannot be invoked.","triggerScenarios":"download() -> api_engine_download() with a MediaInfo whose available_qualities is empty or whose first entry has an empty url field.","commonSituations":"Region-locked, deleted, or audit-pending bilibili content; missing login account/cookies for members-only streams; upstream bilibili API response shape changed so stream URLs were never extracted.","solutions":["Configure a bilibili account (active_account_slug) if the content requires login, and retry.","Confirm the video URL is valid and publicly viewable in a browser first.","Log/inspect the parsed MediaInfo and the parser step to find why no qualities were extracted."],"exampleFix":"// before\nlet url = info.available_qualities.first().map(|q| q.url.as_str()).unwrap_or(\"\");\nif url.is_empty() { return Err(anyhow!(\"No URL available\")); }\n// after\nlet url = info.available_qualities.first().map(|q| q.url.as_str())\n    .filter(|u| !u.is_empty())\n    .with_context(|| format!(\"no stream URL extracted for {} (may require login or be region-locked)\", info.source_url))?;","handlingStrategy":"validation","validationCode":"if !info.available_qualities.iter().any(|q| !q.url.is_empty()) { return Err(anyhow!(\"nothing to download: no stream URL extracted\")); }\napi_engine_download(info, opts, progress).await?;","typeGuard":"fn downloadable(info: &MediaInfo) -> bool { info.available_qualities.iter().any(|q| !q.url.is_empty()) }","tryCatchPattern":null,"preventionTips":["Pre-check available_qualities for a non-empty URL before invoking the API engine path.","Set an active bilibili account slug for login-required content.","Validate the target video in a browser to rule out region/audit restrictions."],"tags":["bilibili","download","empty-url","media-extraction"],"backgroundTag":"empty-required-field","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}