tonhowtf/omniget · error · anyhow::Error
Twitter extraction failed. native=
Error message
Twitter extraction failed. native='{}'; ytdlp='{}' What it means
get_media_info tries native Twitter extraction first and falls back to yt-dlp; this error is raised only when BOTH strategies fail, aggregating both underlying messages into one string. The native error and the yt-dlp error are the real diagnostic payload embedded in the formatted message.
Solutions
- Read both embedded errors: fix the native cause first (usually auth/rate-limit or unavailable tweet) as indicated by native='...'.
- Update yt-dlp to the latest version since stale binaries fail on current X responses.
- Verify the URL is a valid tweet URL extractable to a tweet ID.
- Retry later if the errors indicate rate limiting (HTTP 429) from Twitter endpoints.
- Ensure yt-dlp is installed and on PATH for the fallback path to be meaningful.
Example fix
// before
Err(anyhow!("Twitter extraction failed. native='{}'; ytdlp='{}'", native_err, fallback_err))
// after
#[derive(Debug, thiserror::Error)]
enum TwitterExtractError {
#[error("native extraction failed: {0}")] Native(#[source] anyhow::Error),
#[error("yt-dlp fallback failed: {0}")] Ytdlp(#[source] anyhow::Error),
}
return Err(TwitterExtractError::Ytdlp(fallback_err).into()); // preserves both causes as a chain Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight checks before calling get_media_info
fn preflight_ok(url: &str, ytdlp_path: &str) -> Result<(), String> {
if extract_tweet_id(url).is_none() { return Err("not a tweet URL".into()); }
if !std::path::Path::new(ytdlp_path).exists() { return Err("yt-dlp not found".into()); }
Ok(())
} Try / catch
match get_media_info(url).await {
Ok(info) => download(info),
Err(e) => {
let msg = e.to_string();
if msg.contains("429") { schedule_retry_with_backoff(); }
else if msg.contains("ytdlp=") && msg.contains("not found") { prompt_ytdlp_install(); }
else { show_extraction_failed(&msg); }
}
} Prevention
- Keep yt-dlp updated; both paths failing is often a stale binary plus guest-token trouble.
- Validate the tweet URL before calling extraction.
- Back off and retry on rate-limit signatures in either embedded error.
- Monitor both native and fallback failure rates separately to know which path is degrading.
When it happens
Trigger: native_get_media_info fails (bad URL, GraphQL/syndication blocked, tweet unavailable) AND the subsequent yt-dlp fallback also fails (yt-dlp missing/outdated, network failure, unsupported tweet) — both in one get_media_info call.
Common situations: Twitter/X restricting guest access to GraphQL so native fails, combined with an outdated yt-dlp binary that also fails on new X layouts; offline environments; rate limiting hitting both paths; malformed tweet URLs.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Twitter extraction failed. native=
- Post not available; graphql=
- Post not available; graphql=
- Post not available; graphql=
- Post not available; graphql=
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/2080efc808876e48.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/src/platforms/twitter/mod.rs:830
false
}
async fn get_media_info(&self, url: &str) -> anyhow::Result<MediaInfo> {
match self.native_get_media_info(url).await {
Ok(info) => Ok(info),
Err(native_err) => {
tracing::warn!(
"[twitter] native failed: {}, trying yt-dlp fallback",
native_err
);
match self.fallback_ytdlp(url).await {
Ok(info) => Ok(info),
Err(fallback_err) => {
tracing::warn!(
"[twitter] yt-dlp fallback failed after native error: {}",
fallback_err
);
Err(anyhow!(
"Twitter extraction failed. native='{}'; ytdlp='{}'",
native_err,
fallback_err
))
}
}
}
}
}
async fn download(
&self,
info: &MediaInfo,
opts: &DownloadOptions,
progress: mpsc::Sender<ProgressUpdate>,
) -> anyhow::Result<DownloadResult> {
if let Some(quality) = info.available_qualities.first() {
if quality.format == "ytdlp" {View on GitHub (pinned to 8600b91f42)