{"record":{"id":"e9a48cd04a620b06","repo":"ytdl-org/youtube-dl","slug":"s-said-s-e9a48c","errorCode":null,"errorMessage":"%s said: %s","messagePattern":"%s said: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/msn.py","lineNumber":169,"sourceCode":"            entries.append({\n                'id': video_id,\n                'display_id': display_id,\n                'title': title,\n                'description': video.get('description'),\n                'thumbnail': video.get('headlineImage', {}).get('url'),\n                'duration': int_or_none(video.get('durationSecs')),\n                'uploader': video.get('sourceFriendly'),\n                'uploader_id': video.get('providerId'),\n                'creator': video.get('creator'),\n                'subtitles': subtitles,\n                'formats': formats,\n            })\n\n        if not entries:\n            error = unescapeHTML(self._search_regex(\n                r'data-error=([\"\\'])(?P<error>.+?)\\1',\n                webpage, 'error', group='error'))\n            raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True)\n\n        return self.playlist_result(entries, page_id)\n","sourceCodeStart":151,"sourceCodeEnd":172,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/msn.py#L151-L172","documentation":"Raised by the MSN extractor when the playlist-parsing pass produced zero entries, and the webpage instead carries a data-error=\"...\" attribute. The extractor surfaces the site's own error text (e.g. content removed or region unavailable) prefixed with 'MSN said:'. It is expected=True, so it terminates that URL cleanly.","triggerScenarios":"Calling the MSNIE on an MSN video/playlist page whose JSON blob yields no entries and whose HTML contains a data-error='...' attribute, which is unescaped and reported verbatim.","commonSituations":"Dead or removed MSN embeds; region-locked MSN content; MSN page layout/JSON changes after an extractor update lags; URLs scraped from third-party sites that reference expired articles.","solutions":["Read the embedded site message — it is the site's own explanation (removal, geo block) and dictates what to do next.","Verify the URL still plays in a browser; if not, the link is dead and no tool can download it.","Update youtube-dl/youtube-dl to get the latest MSN extractor in case the page format changed.","If the content is geo-blocked, retry with --geo-verify-proxy or a proxy for the allowed region."],"exampleFix":"youtube-dl --geo-verify-proxy 'https://www.msn.com/en-us/video/...'","handlingStrategy":"try-catch","validationCode":"import requests\nhtml = requests.get(url).text\nimport re\nm = re.search(r'data-error=([\"\\'])(?P<e>.+?)\\1', html)\nif m and '<video' not in html.lower():\n    print('site error:', m.group('e'))  # skip before invoking the extractor","typeGuard":null,"tryCatchPattern":"except ExtractorError as e:\n    if e.expected and str(e).startswith('MSN said:'):\n        record_site_error(url, str(e))  # message carries the site's own reason\n    else:\n        raise","preventionTips":["Validate MSN links resolve (HTTP 200 and contain player markup) before batch extraction.","Cache the site's data-error text — it distinguishes removal from geo blocks.","Update the extractor regularly; MSN page structure changes often."],"tags":["site-error","extractor","expected-error","content-unavailable"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}