ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

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.

Source

Thrown at youtube_dl/extractor/aol.py:94

    }, {
        'url': 'https://www.aol.jp/video/playlist/5a28e936a1334d000137da0c/5a28f3151e642219fde19831/',
        'only_matching': True,
    }, {
        # Yahoo video
        'url': 'https://www.aol.com/video/play/991e6700-ac02-11ea-99ff-357400036f61/24bbc846-3e30-3c46-915e-fe8ccd7fcc46/',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        if '-' in video_id:
            return self._extract_yahoo_video(video_id, 'us')

        response = self._download_json(
            'https://feedapi.b2c.on.aol.com/v1.0/app/videos/aolon/%s/details' % video_id,
            video_id)['response']
        if response['statusText'] != 'Ok':
            raise ExtractorError('%s said: %s' % (self.IE_NAME, response['statusText']), expected=True)

        video_data = response['data']
        formats = []
        m3u8_url = url_or_none(video_data.get('videoMasterPlaylist'))
        if m3u8_url:
            formats.extend(self._extract_m3u8_formats(
                m3u8_url, video_id, 'mp4', m3u8_id='hls', fatal=False))
        for rendition in video_data.get('renditions', []):
            video_url = url_or_none(rendition.get('url'))
            if not video_url:
                continue
            ext = rendition.get('format')
            if ext == 'm3u8':
                formats.extend(self._extract_m3u8_formats(
                    video_url, video_id, 'mp4', m3u8_id='hls', fatal=False))
            else:
                f = {
                    'url': video_url,

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Trust the embedded statusText — 'Not Found'-style values mean the video is gone from the feed
  2. Note that ids containing '-' are routed to the Yahoo extractor; make sure the id is not a Yahoo one misparsed
  3. Search the original article page for a current canonical video URL
Defensive patterns

Strategy: try-catch

Validate before calling

# Optional pre-check of the AOL feed status
import requests
resp = requests.get('https://feedapi.b2c.on.aol.com/v1.0/app/videos/aolon/%s/details' % video_id).json()['response']
if resp.get('statusText') != 'Ok':
    skip(url, reason=resp.get('statusText'))

Try / catch

try:
    ydl.extract_info(url)
except ExtractorError as e:
    if 'AOL said:' in str(e):
        mark_url_dead(url)  # feed refused the id; typically permanent

Prevention

When it happens

Trigger: 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.

Common situations: Dead AOL video links from old articles; ids for videos delisted after licensing expiry; AOL feed decommissioning over time.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/b308e8da5450843e. Report an issue: GitHub.