tonhowtf/omniget · error

No HLS URL available

Error message

No HLS URL available

What it means

Thrown in BlueskyDownloader::download for MediaType::Video when info.available_qualities is empty, so there is no HLS URL to feed the HLS downloader. The MediaInfo passed in is inconsistent with its media_type — a video entry must have at least one quality entry.

Solutions

  1. Check available_qualities is non-empty before calling download() with MediaType::Video.
  2. Re-fetch media info via get_media_info to repopulate qualities.
  3. If using the yt-dlp path, keep the quality with format == "ytdlp" so it routes correctly.
  4. Validate MediaInfo (media_type vs qualities) at construction time.

Example fix

// before
let info = MediaInfo { media_type: MediaType::Video, available_qualities: vec![], .. };
downloader.download(&info, &opts, tx).await?;
// after
assert!(!info.available_qualities.is_empty(), "video MediaInfo needs at least one quality");
Defensive patterns

Strategy: validation

Validate before calling

if info.media_type == MediaType::Video && info.available_qualities.is_empty() {
    return Err(anyhow!("video MediaInfo has no qualities; refetch via get_media_info"));
}

Type guard

fn has_video_qualities(info: &MediaInfo) -> bool {
    matches!(info.media_type, MediaType::Video) && info.available_qualities.iter().any(|q| !q.url.is_empty())
}

Try / catch

match downloader.download(&info, &opts, tx).await {
    Err(e) if e.to_string() == "No HLS URL available" => {
        let fresh = downloader.get_media_info(&original_url).await?;
        downloader.download(&fresh, &opts, tx).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling download() with a hand-constructed or yt-dlp-parsed MediaInfo whose media_type is Video but available_qualities is an empty vec, or after the single quality was stripped.

Common situations: Constructing MediaInfo programmatically and forgetting qualities, third-party code filtering qualities (e.g. by format) down to zero, or deserializing partial metadata.

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

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/bluesky.rs:280

                    opts.filename_template.as_deref(),
                    opts.referer.as_deref().or(Some("https://bsky.app")),
                    opts.cancel_token.clone(),
                    None,
                    opts.concurrent_fragments,
                    false,
                    &[],
                    opts.audio_format.as_deref(),
                )
                .await;
            }
        }

        match info.media_type {
            MediaType::Video => {
                let hls_url = &info
                    .available_qualities
                    .first()
                    .ok_or_else(|| anyhow!("No HLS URL available"))?
                    .url;

                let filename = format!("{}.mp4", sanitize_filename::sanitize(&info.title));
                let output_path = opts.output_dir.join(&filename);
                let output_str = output_path.to_string_lossy().to_string();

                let downloader =
                    HlsDownloader::new().with_user_agent_override(opts.user_agent.clone());
                let _ = progress.send(ProgressUpdate::percent(0.0)).await;

                let result = downloader
                    .download(
                        hls_url,
                        &output_str,
                        "https://bsky.app",
                        None,
                        opts.cancel_token.clone(),
                        20,

View on GitHub (pinned to 8600b91f42)