ytdl-org/youtube-dl · warning · ExtractorError
There's no video in this tweet.
Error message
There's no video in this tweet.
What it means
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.
Source
Thrown at youtube_dl/extractor/twitter.py:572
if not image_url or '/player-placeholder' in image_url:
continue
thumbnails.append({
'id': suffix[1:] if suffix else 'medium',
'url': image_url,
'width': int_or_none(image.get('width')),
'height': int_or_none(image.get('height')),
})
info.update({
'formats': formats,
'thumbnails': thumbnails,
'duration': int_or_none(get_binding_value(
'content_duration_seconds')),
})
else:
expanded_url = try_get(status, lambda x: x['entities']['urls'][0]['expanded_url'])
if not expanded_url:
raise ExtractorError("There's no video in this tweet.")
info.update({
'_type': 'url',
'url': expanded_url,
})
return info
class TwitterAmplifyIE(TwitterBaseIE):
IE_NAME = 'twitter:amplify'
_VALID_URL = r'https?://amp\.twimg\.com/v/(?P<id>[0-9a-f\-]{36})'
_TEST = {
'url': 'https://amp.twimg.com/v/0ba0c3c7-0af3-4c0a-bed5-7efd1ffa2951',
'md5': '7df102d0b9fd7066b86f3159f8e81bf6',
'info_dict': {
'id': '0ba0c3c7-0af3-4c0a-bed5-7efd1ffa2951',
'ext': 'mp4',
'title': 'Twitter Video',View on GitHub (pinned to 956b8c5855)
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.
Defensive patterns
Strategy: validation
Validate before calling
import requests
o = requests.get('https://publish.twitter.com/oembed', params={'url': tweet_url}).json()
if '<video' not in o.get('html', '') and 'video' not in o.get('type', ''):
skip(tweet_url, 'no media in tweet') Type guard
def tweet_has_video(status: dict) -> bool:
urls = ((status.get('entities') or {}).get('urls') or [])
return any('video_info' in (bv or {}) for bv in status.get('extended_entities', {}).get('media', [])) or bool(urls) Try / catch
try:
ydl.extract_info(tweet_url)
except ExtractorError as e:
if "no video in this tweet" in str(e):
continue # benign: text/image tweet in a batch list
else:
raise Prevention
- 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.
When it happens
Trigger: 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).
Common situations: Feeding status URLs for text/image tweets into batch scripts, tweet permalink without media, Twitter frontend changes breaking entity scraping in old builds.
Related errors
- Episode %s is not currently available
- Simplestream ID not found
- Unsupported URL: %s
- Redirect loop: %s
- No sources found for video %s. Maybe a plain image?
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/c8ac27e7223a231c.
Report an issue: GitHub.