tonhowtf/omniget · error

No downloadable media found in Threads post

Error message

No downloadable media found in Threads post

What it means

download in threads.rs inspects info.available_qualities.len() and raises this error when it is zero. It means a MediaInfo reached the download stage with no selectable quality/media entries, so there is nothing to download. Usually indicates get_media_info produced an empty quality list despite succeeding.

Solutions

  1. Verify available_qualities is non-empty before calling download
  2. Check the code path that populates available_qualities from extracted media for silent skips
  3. Re-fetch media info (get_media_info) to get a fresh MediaInfo before downloading
  4. Return a clearer 'media list empty, re-fetch info' error to the caller

Example fix

// before
if count == 0 {
    return Err(anyhow!("No downloadable media found in Threads post"));
}
// after
if count == 0 {
    return Err(anyhow!("No downloadable media found in Threads post; re-fetch media info"));
}
Defensive patterns

Strategy: validation

Validate before calling

if (!info || !Array.isArray(info.available_qualities) || info.available_qualities.length === 0) {
  throw new Error("MediaInfo has no downloadable qualities; re-fetch media info first");
}

Type guard

function isDownloadable(info) {
  return Array.isArray(info?.available_qualities) && info.available_qualities.length > 0;
}

Try / catch

match threads.download(&info, tx).await {
    Err(e) if e.to_string().contains("No downloadable media") => {
        // refresh info once, then retry
        let fresh = threads.get_media_info(url).await?;
        threads.download(&fresh, tx).await?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling download with a Threads MediaInfo whose available_qualities is empty — e.g. extract_media_from_post built items but none were mapped into qualities, or the caller constructed MediaInfo manually.

Common situations: Schema changes making the quality-population step silently skip all items; race where the post's media was removed between info and download; callers reusing a MediaInfo from a different (media-less) post.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/ce7b2e66de1e5834. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/threads.rs:482

                    thumbnail_url,
                    available_qualities: qualities,
                    media_type: MediaType::Carousel,
                    file_size_bytes: None,
                })
            }
        }
    }

    async fn download(
        &self,
        info: &MediaInfo,
        opts: &DownloadOptions,
        progress: mpsc::Sender<ProgressUpdate>,
    ) -> anyhow::Result<DownloadResult> {
        let count = info.available_qualities.len();

        if count == 0 {
            return Err(anyhow!("No downloadable media found in Threads post"));
        }

        if count == 1 {
            let quality = info.available_qualities.first().unwrap();
            let filename = format!(
                "{}.{}",
                sanitize_filename::sanitize(&info.title),
                quality.format
            );
            let output = opts.output_dir.join(&filename);

            let mut hdr_map = Self::threads_headers();
            crate::core::http_client::inject_ua_header(&mut hdr_map, opts.user_agent.as_deref());
            let headers = Some(hdr_map);

            let bytes = download_direct_with_headers(
                &self.client,
                &quality.url,

View on GitHub (pinned to 8600b91f42)