tonhowtf/omniget · error · anyhow::Error
Failed to detect URL kind
Error message
Failed to detect URL kind: {} What it means
`api_engine_download` resolves b23.tv short links, then calls `url_kind::detect(&effective_url)` to classify the URL (video, audio, article, etc.). If detection fails, the error's i18n key is wrapped with `anyhow!("Failed to detect URL kind: {}")`. Without a kind, the engine cannot choose a parser.
Solutions
- Verify the URL is a supported Bilibili content URL (video BV/AV, etc.) before calling download.
- Ensure b23.tv short links can be resolved (network access); paste the expanded URL if resolution fails.
- Update the app — new Bilibili URL formats require updated detection rules.
- Map the error's i18n key to a user-facing message and prompt for a corrected link.
Example fix
// before
let url = "https://example.com/not-bilibili";
download(info_from(url), opts, progress).await?; // Failed to detect URL kind
// after
if !url.contains("bilibili.com") && !url.contains("b23.tv") {
return Err(anyhow!("not a Bilibili URL"));
}
download(info_from(url), opts, progress).await?; Defensive patterns
Strategy: validation
Validate before calling
fn looks_like_bilibili(url: &str) -> bool {
url.contains("bilibili.com") || url.contains("b23.tv")
}
if !looks_like_bilibili(&effective_url) { return Err(anyhow!("unsupported URL")); } Try / catch
match download(info, opts, progress).await {
Err(e) if e.to_string().contains("Failed to detect URL kind") => ask_user_for_valid_link(),
Err(e) => return Err(e),
Ok(_) => {},
} Prevention
- Validate that the input is a supported Bilibili URL before calling download.
- Expand b23.tv short links and handle resolution failures explicitly.
- Keep the app updated for new Bilibili URL formats.
- Reject obviously non-Bilibili links in the UI input layer.
When it happens
Trigger: Calling `download` with a URL that `url_kind::detect` cannot classify — not a valid Bilibili URL at all, a b23.tv link that failed to resolve and remains a short URL, malformed video ID/BV numbers, or unsupported URL shapes (live rooms, space pages) the detector doesn't handle.
Common situations: Users pasting arbitrary web pages or non-Bilibili links; b23.tv short-link resolution failing due to network/redirect changes; new Bilibili URL formats not yet supported by the detector; typos in BV/AV ids.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Could not extract post ID
- não reconheci um vídeo do Bilibili em
- Could not extract pin ID
- Expected a JSON array of cookie objects.
- cor inválida
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/968a00486e128873.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/platforms/bilibili/mod.rs:122
.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()))?;
let settings = crate::storage::config::load_settings_standalone();
let container = mux::container_from_setting(&settings.download.bilibili_container);
let danmaku_format = danmaku_format_from_setting(&settings.download.bilibili_danmaku_format);
let cover_format = cover::CoverFormat::from_str(&settings.download.bilibili_cover_format);
let template_set = naming::TemplateSet {
video: settings.download.bilibili_naming_video.clone(),
multi_part: settings.download.bilibili_naming_multi_part.clone(),
bangumi: settings.download.bilibili_naming_bangumi.clone(),
cheese: settings.download.bilibili_naming_cheese.clone(),
collection: settings.download.bilibili_naming_collection.clone(),
};
let first_item_owned = parsed.items.first().cloned().unwrap_or_default();
let naming_kind = naming::classify(&kind, &first_item_owned);
let naming_inputs = naming::NamingInputs {View on GitHub (pinned to 8600b91f42)