ytdl-org/youtube-dl · error · ExtractorError
No video formats found!
Error message
No video formats found!
What it means
Raised by xpath_attr when no element matching (xpath, key) has the requested attribute — find_xpath_attr returns None, no default is given, and fatal=True. It is the attribute-counterpart of the element error: the element may exist, but the @key attribute the extractor requires is missing.
Source
Thrown at youtube_dl/YoutubeDL.py:1759
else:
formats = info_dict['formats']
def is_wellformed(f):
url = f.get('url')
if not url:
self.report_warning(
'"url" field is missing or empty - skipping format, '
'there is an error in extractor')
return False
if isinstance(url, bytes):
sanitize_string_field(f, 'url')
return True
# Filter out malformed formats for better extraction robustness
formats = list(filter(is_wellformed, formats or []))
if not formats:
raise ExtractorError('No video formats found!')
formats_dict = {}
# We check that all the formats have the format and format_id fields
for i, format in enumerate(formats):
sanitize_string_field(format, 'format_id')
sanitize_numeric_fields(format)
format['url'] = sanitize_url(format['url'])
if not format.get('format_id'):
format['format_id'] = compat_str(i)
else:
# Sanitize format_id from characters used in format selector expression
format['format_id'] = re.sub(r'[\s,/+\[\]()]', '_', format['format_id'])
format_id = format['format_id']
if format_id not in formats_dict:
formats_dict[format_id] = []
formats_dict[format_id].append(format)
View on GitHub (pinned to 956b8c5855)
Solutions
- Pass default=None / fatal=False and handle the miss at the call site when the attribute is genuinely optional.
- Dump the received XML and confirm the attribute name — update the XPath to '//Stream[@url]' or read the renamed attribute.
- Update youtube-dl / use yt-dlp for built-in extractor breakage.
- Provide name='stream url' to get a human-readable error identifying the field.
Example fix
# before url = xpath_attr(fmt, 'Stream', 'url', fatal=True) # after url = xpath_attr(fmt, 'Stream', 'url', default=None) or xpath_text(fmt, 'Stream/url')
Defensive patterns
Strategy: validation
Validate before calling
from youtube_dl.utils import find_xpath_attr
# pre-check attribute presence
node = find_xpath_attr(doc, '//Stream', 'url')
if node is None:
url = fallback_url
else:
url = node.attrib['url'] Try / catch
from youtube_dl.utils import ExtractorError, xpath_attr
try:
url = xpath_attr(node, 'Stream', 'url', name='stream url', fatal=True)
except ExtractorError as e:
if 'Could not find XML attribute' in str(e):
url = xpath_text(node, 'Stream/text()', default=None) # schema moved it
else:
raise Prevention
- Supply default= for optional attributes and handle None explicitly.
- Verify attribute names against a dumped response — renames (url→href) are the usual cause.
- Use name= to get readable diagnostics naming the missing field.
When it happens
Trigger: xpath_attr(node, '//Stream', 'url', fatal=True) where the Stream nodes lack a url attribute (renamed to href, moved to child text, or dropped). The message shows 'xpath[@key]' (or the caller's name=) identifying the exact attribute expected.
Common situations: API schema changes renaming attributes; conditional attributes only present for some items; responses from a different endpoint/version than the extractor expects; namespace-qualified attributes the plain XPath misses.
Related errors
- Missing "id" field in extractor result
- Missing "title" field in extractor result
- Failed to get the video URL
- Invalid rendition field.
- Invalid metadata XML file
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/68a34f534b9951e9.
Report an issue: GitHub.