tonhowtf/omniget · error
No media found in tweet
Error message
No media found in tweet
What it means
Raised when the tweet result __typename is "Tweet" (or TweetWithVisibilityResults) but media_arrays_from_tweet_result returns None — the tweet resolved successfully yet contains no media arrays (photos/videos) at the expected JSON paths. It specifically means 'this post exists but has no downloadable media', not that the post is unavailable.
Solutions
- Check the tweet actually contains media (photos/videos) before calling the extraction API.
- Log the tweet legacy entities to confirm whether media keys moved in the current schema.
- Update media_arrays_from_tweet_result to also check newer paths (e.g. views/media under the unified result).
- Return a distinct 'no media' typed error so callers can distinguish it from 'post unavailable'.
Example fix
// before
let media = Self::media_arrays_from_tweet_result(tweet_result)
.ok_or_else(|| anyhow!("No media found in tweet"))?;
// after
let media = Self::media_arrays_from_tweet_result(tweet_result)
.ok_or_else(|| TwitterError::NoMedia { tweet_id })?; Defensive patterns
Strategy: validation
Validate before calling
// Check for media keys before extraction:
let has_media = tweet_result.pointer("/legacy/extended_entities/media").is_some()
|| tweet_result.pointer("/legacy/entities/media").is_some();
if !has_media {
return Err(DisplayError::NoMedia);
} Type guard
fn tweet_has_media(tweet_result: &serde_json::Value) -> bool {
tweet_result.pointer("/legacy/extended_entities/media")
.or_else(|| tweet_result.pointer("/legacy/entities/media"))
.and_then(|v| v.as_array())
.map(|a| !a.is_empty())
.unwrap_or(false)
} Try / catch
match extractor.fetch_media(tweet_url) {
Err(e) if e.to_string() == "No media found in tweet" => {
ui.show("This tweet contains no photos or videos.");
}
other => other?,
} Prevention
- Check the tweet's entities/extended_entities for media before requesting a download.
- Distinguish 'no media' from 'post unavailable' in your own error handling.
- Handle text-only, poll, and link-only tweets explicitly in the UI.
- Watch for schema drift in legacy entity paths when media exists but extraction fails.
When it happens
Trigger: Calling the media-extraction API on a text-only tweet, a poll, or a link-only tweet; also when schema drift moves extended_entities/media keys so the extractor can't find them even though media exists.
Common situations: Users paste links to plain-text tweets expecting a download; deleted media (tweet edited/media removed); Twitter renaming legacy entities fields in newer GraphQL payloads.
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
- Post not available; graphql=
- No photo URLs found in HTML
- Post not available; graphql=
- empty stream url
- nenhum favorito foi lido: esses perfis costumam exigir a…
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/5c8d4fc41290bf79.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/platforms/twitter.rs:471
.and_then(|v| v.as_str())
.unwrap_or("");
tracing::warn!(
"[twitter] graphql tombstone tweet_id={} reason='{}' tombstone_text='{}'",
tweet_id,
reason,
tombstone_text
);
if reason == "NsfwLoggedOut" || tombstone_text.starts_with("Age-restricted") {
return Err(anyhow!("Age-restricted content"));
}
Err(anyhow!("Post not available"))
}
"Tweet" | "TweetWithVisibilityResults" => {
let media = Self::media_arrays_from_tweet_result(tweet_result)
.ok_or_else(|| anyhow!("No media found in tweet"))?;
tracing::debug!(
"[twitter] graphql extracted {} media entries for tweet_id={}",
media.len(),
tweet_id
);
Ok(media)
}
_ => Err(anyhow!("Post not available")),
}
}
fn extract_syndication_media(
json: &serde_json::Value,
) -> anyhow::Result<Vec<serde_json::Value>> {
let typename = json
.get("__typename")
.and_then(|v| v.as_str())
.unwrap_or("");View on GitHub (pinned to 8600b91f42)