{"record":{"id":"c8ac27e7223a231c","repo":"ytdl-org/youtube-dl","slug":"there-s-no-video-in-this-tweet","errorCode":null,"errorMessage":"There's no video in this tweet.","messagePattern":"There's no video in this tweet\\.","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"warning","filePath":"youtube_dl/extractor/twitter.py","lineNumber":572,"sourceCode":"                        if not image_url or '/player-placeholder' in image_url:\n                            continue\n                        thumbnails.append({\n                            'id': suffix[1:] if suffix else 'medium',\n                            'url': image_url,\n                            'width': int_or_none(image.get('width')),\n                            'height': int_or_none(image.get('height')),\n                        })\n\n                    info.update({\n                        'formats': formats,\n                        'thumbnails': thumbnails,\n                        'duration': int_or_none(get_binding_value(\n                            'content_duration_seconds')),\n                    })\n            else:\n                expanded_url = try_get(status, lambda x: x['entities']['urls'][0]['expanded_url'])\n                if not expanded_url:\n                    raise ExtractorError(\"There's no video in this tweet.\")\n                info.update({\n                    '_type': 'url',\n                    'url': expanded_url,\n                })\n        return info\n\n\nclass TwitterAmplifyIE(TwitterBaseIE):\n    IE_NAME = 'twitter:amplify'\n    _VALID_URL = r'https?://amp\\.twimg\\.com/v/(?P<id>[0-9a-f\\-]{36})'\n\n    _TEST = {\n        'url': 'https://amp.twimg.com/v/0ba0c3c7-0af3-4c0a-bed5-7efd1ffa2951',\n        'md5': '7df102d0b9fd7066b86f3159f8e81bf6',\n        'info_dict': {\n            'id': '0ba0c3c7-0af3-4c0a-bed5-7efd1ffa2951',\n            'ext': 'mp4',\n            'title': 'Twitter Video',","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/twitter.py#L554-L590","documentation":"Raised by TwitterIE when a tweet contains no recognized video binding values and no expanded URL in status.entities.urls[0] — i.e. the tweet is text/image only and there is nothing to download. Notably this ExtractorError is NOT marked expected=True, so youtube-dl logs it as a regular extraction error rather than a benign 'no video' notice.","triggerScenarios":"Extracting a tweet whose entities contain neither video_info/animated_gif bindings nor any expanded_url (plain text tweet, image-only tweet, or a Twitter API/HTML change that hides entities from the extractor).","commonSituations":"Feeding status URLs for text/image tweets into batch scripts, tweet permalink without media, Twitter frontend changes breaking entity scraping in old builds.","solutions":["Confirm the tweet actually contains video (play it in a browser); if not, skip such URLs in your pipeline.","If the tweet does have video, update youtube-dl / use yt-dlp — Twitter's markup changed repeatedly and old scrapers miss entities.","For image tweets, download images directly (youtube-dl does not handle plain images).","Pre-filter URLs with a check of oembed metadata before invoking the extractor."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import requests\no = requests.get('https://publish.twitter.com/oembed', params={'url': tweet_url}).json()\nif '<video' not in o.get('html', '') and 'video' not in o.get('type', ''):\n    skip(tweet_url, 'no media in tweet')","typeGuard":"def tweet_has_video(status: dict) -> bool:\n    urls = ((status.get('entities') or {}).get('urls') or [])\n    return any('video_info' in (bv or {}) for bv in status.get('extended_entities', {}).get('media', [])) or bool(urls)","tryCatchPattern":"try:\n    ydl.extract_info(tweet_url)\nexcept ExtractorError as e:\n    if \"no video in this tweet\" in str(e):\n        continue  # benign: text/image tweet in a batch list\n    else:\n        raise","preventionTips":["Pre-filter tweet URLs via the oembed endpoint so only media tweets reach the extractor.","Keep youtube-dl/yt-dlp current: Twitter markup changes frequently and stale builds misreport real videos as empty."],"tags":["twitter","no-media","scraping","filtering"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}