{"record":{"id":"68a34f534b9951e9","repo":"ytdl-org/youtube-dl","slug":"no-video-formats-found","errorCode":null,"errorMessage":"No video formats found!","messagePattern":"No video formats found!","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/YoutubeDL.py","lineNumber":1759,"sourceCode":"        else:\n            formats = info_dict['formats']\n\n        def is_wellformed(f):\n            url = f.get('url')\n            if not url:\n                self.report_warning(\n                    '\"url\" field is missing or empty - skipping format, '\n                    'there is an error in extractor')\n                return False\n            if isinstance(url, bytes):\n                sanitize_string_field(f, 'url')\n            return True\n\n        # Filter out malformed formats for better extraction robustness\n        formats = list(filter(is_wellformed, formats or []))\n\n        if not formats:\n            raise ExtractorError('No video formats found!')\n\n        formats_dict = {}\n\n        # We check that all the formats have the format and format_id fields\n        for i, format in enumerate(formats):\n            sanitize_string_field(format, 'format_id')\n            sanitize_numeric_fields(format)\n            format['url'] = sanitize_url(format['url'])\n            if not format.get('format_id'):\n                format['format_id'] = compat_str(i)\n            else:\n                # Sanitize format_id from characters used in format selector expression\n                format['format_id'] = re.sub(r'[\\s,/+\\[\\]()]', '_', format['format_id'])\n            format_id = format['format_id']\n            if format_id not in formats_dict:\n                formats_dict[format_id] = []\n            formats_dict[format_id].append(format)\n","sourceCodeStart":1741,"sourceCodeEnd":1777,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/YoutubeDL.py#L1741-L1777","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nurl = xpath_attr(fmt, 'Stream', 'url', fatal=True)\n\n# after\nurl = xpath_attr(fmt, 'Stream', 'url', default=None) or xpath_text(fmt, 'Stream/url')","handlingStrategy":"validation","validationCode":"from youtube_dl.utils import find_xpath_attr\n\n# pre-check attribute presence\nnode = find_xpath_attr(doc, '//Stream', 'url')\nif node is None:\n    url = fallback_url\nelse:\n    url = node.attrib['url']","typeGuard":null,"tryCatchPattern":"from youtube_dl.utils import ExtractorError, xpath_attr\ntry:\n    url = xpath_attr(node, 'Stream', 'url', name='stream url', fatal=True)\nexcept ExtractorError as e:\n    if 'Could not find XML attribute' in str(e):\n        url = xpath_text(node, 'Stream/text()', default=None)  # schema moved it\n    else:\n        raise","preventionTips":["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."],"tags":["xml","xpath","attributes","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}