{"record":{"id":"b308e8da5450843e","repo":"ytdl-org/youtube-dl","slug":"s-said-s-b308e8","errorCode":null,"errorMessage":"%s said: %s","messagePattern":"%s said: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/aol.py","lineNumber":94,"sourceCode":"    }, {\n        'url': 'https://www.aol.jp/video/playlist/5a28e936a1334d000137da0c/5a28f3151e642219fde19831/',\n        'only_matching': True,\n    }, {\n        # Yahoo video\n        'url': 'https://www.aol.com/video/play/991e6700-ac02-11ea-99ff-357400036f61/24bbc846-3e30-3c46-915e-fe8ccd7fcc46/',\n        'only_matching': True,\n    }]\n\n    def _real_extract(self, url):\n        video_id = self._match_id(url)\n        if '-' in video_id:\n            return self._extract_yahoo_video(video_id, 'us')\n\n        response = self._download_json(\n            'https://feedapi.b2c.on.aol.com/v1.0/app/videos/aolon/%s/details' % video_id,\n            video_id)['response']\n        if response['statusText'] != 'Ok':\n            raise ExtractorError('%s said: %s' % (self.IE_NAME, response['statusText']), expected=True)\n\n        video_data = response['data']\n        formats = []\n        m3u8_url = url_or_none(video_data.get('videoMasterPlaylist'))\n        if m3u8_url:\n            formats.extend(self._extract_m3u8_formats(\n                m3u8_url, video_id, 'mp4', m3u8_id='hls', fatal=False))\n        for rendition in video_data.get('renditions', []):\n            video_url = url_or_none(rendition.get('url'))\n            if not video_url:\n                continue\n            ext = rendition.get('format')\n            if ext == 'm3u8':\n                formats.extend(self._extract_m3u8_formats(\n                    video_url, video_id, 'mp4', m3u8_id='hls', fatal=False))\n            else:\n                f = {\n                    'url': video_url,","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/aol.py#L76-L112","documentation":"Raised by the AOL extractor when feedapi.b2c.on.aol.com returns a response whose statusText is not 'Ok'. The site's own status text is embedded in the message. Marked expected=True, meaning the feed API answered but refused the request for the given video id.","triggerScenarios":"GET /v1.0/app/videos/aolon/<id>/details returns response.statusText like 'Not Found' or 'Invalid video'; deleted or unpublished AOL videos; ids that only exist in other regions.","commonSituations":"Dead AOL video links from old articles; ids for videos delisted after licensing expiry; AOL feed decommissioning over time.","solutions":["Trust the embedded statusText — 'Not Found'-style values mean the video is gone from the feed","Note that ids containing '-' are routed to the Yahoo extractor; make sure the id is not a Yahoo one misparsed","Search the original article page for a current canonical video URL"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# Optional pre-check of the AOL feed status\nimport requests\nresp = requests.get('https://feedapi.b2c.on.aol.com/v1.0/app/videos/aolon/%s/details' % video_id).json()['response']\nif resp.get('statusText') != 'Ok':\n    skip(url, reason=resp.get('statusText'))","typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if 'AOL said:' in str(e):\n        mark_url_dead(url)  # feed refused the id; typically permanent","preventionTips":["Remember ids containing '-' go to the Yahoo path — id shape determines which API is called","Treat AOL feed failures as permanent (delisted content) unless the statusText says otherwise"],"tags":["aol","feed-api","content-missing","server-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}