{"record":{"id":"5c8d4fc41290bf79","repo":"tonhowtf/omniget","slug":"no-media-found-in-tweet","errorCode":null,"errorMessage":"No media found in tweet","messagePattern":"No media found in tweet","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/platforms/twitter.rs","lineNumber":471,"sourceCode":"                    .and_then(|v| v.as_str())\n                    .unwrap_or(\"\");\n\n                tracing::warn!(\n                    \"[twitter] graphql tombstone tweet_id={} reason='{}' tombstone_text='{}'\",\n                    tweet_id,\n                    reason,\n                    tombstone_text\n                );\n\n                if reason == \"NsfwLoggedOut\" || tombstone_text.starts_with(\"Age-restricted\") {\n                    return Err(anyhow!(\"Age-restricted content\"));\n                }\n\n                Err(anyhow!(\"Post not available\"))\n            }\n            \"Tweet\" | \"TweetWithVisibilityResults\" => {\n                let media = Self::media_arrays_from_tweet_result(tweet_result)\n                    .ok_or_else(|| anyhow!(\"No media found in tweet\"))?;\n                tracing::debug!(\n                    \"[twitter] graphql extracted {} media entries for tweet_id={}\",\n                    media.len(),\n                    tweet_id\n                );\n                Ok(media)\n            }\n            _ => Err(anyhow!(\"Post not available\")),\n        }\n    }\n\n    fn extract_syndication_media(\n        json: &serde_json::Value,\n    ) -> anyhow::Result<Vec<serde_json::Value>> {\n        let typename = json\n            .get(\"__typename\")\n            .and_then(|v| v.as_str())\n            .unwrap_or(\"\");","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/platforms/twitter.rs#L453-L489","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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'."],"exampleFix":"// before\nlet media = Self::media_arrays_from_tweet_result(tweet_result)\n    .ok_or_else(|| anyhow!(\"No media found in tweet\"))?;\n// after\nlet media = Self::media_arrays_from_tweet_result(tweet_result)\n    .ok_or_else(|| TwitterError::NoMedia { tweet_id })?;","handlingStrategy":"validation","validationCode":"// Check for media keys before extraction:\nlet has_media = tweet_result.pointer(\"/legacy/extended_entities/media\").is_some()\n    || tweet_result.pointer(\"/legacy/entities/media\").is_some();\nif !has_media {\n    return Err(DisplayError::NoMedia);\n}","typeGuard":"fn tweet_has_media(tweet_result: &serde_json::Value) -> bool {\n    tweet_result.pointer(\"/legacy/extended_entities/media\")\n        .or_else(|| tweet_result.pointer(\"/legacy/entities/media\"))\n        .and_then(|v| v.as_array())\n        .map(|a| !a.is_empty())\n        .unwrap_or(false)\n}","tryCatchPattern":"match extractor.fetch_media(tweet_url) {\n    Err(e) if e.to_string() == \"No media found in tweet\" => {\n        ui.show(\"This tweet contains no photos or videos.\");\n    }\n    other => other?,\n}","preventionTips":["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."],"tags":["twitter","media-extraction","empty-result","scraping"],"backgroundTag":"empty-result-set","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}