ytdl-org/youtube-dl · error · ExtractorError

%s returned error: %s

Error message

%s returned error: %s

What it means

Raised by PlayFMIE when the v2api.play.fm recordings lookup returns a top-level 'error' dict. The message interpolates the extractor name and the API's own error.message. Expected=True — the API answered, but negatively (e.g. recording not found).

Source

Thrown at youtube_dl/extractor/playfm.py:47

            'upload_date': '20140722',
            'uploader': 'Dan Drastic',
            'uploader_id': '71170',
            'view_count': int,
            'comment_count': int,
        },
    }

    def _real_extract(self, url):
        mobj = re.match(self._VALID_URL, url)
        video_id = mobj.group('id')
        slug = mobj.group('slug')

        recordings = self._download_json(
            'http://v2api.play.fm/recordings/slug/%s' % slug, video_id)

        error = recordings.get('error')
        if isinstance(error, dict):
            raise ExtractorError(
                '%s returned error: %s' % (self.IE_NAME, error.get('message')),
                expected=True)

        audio_url = recordings['audio']
        video_id = compat_str(recordings.get('id') or video_id)
        title = recordings['title']
        description = recordings.get('description')
        duration = int_or_none(recordings.get('recordingDuration'))
        timestamp = parse_iso8601(recordings.get('created_at'))
        uploader = recordings.get('page', {}).get('title')
        uploader_id = compat_str(recordings.get('page', {}).get('id'))
        view_count = int_or_none(recordings.get('playCount'))
        comment_count = int_or_none(recordings.get('commentCount'))
        categories = [tag['name'] for tag in recordings.get('tags', []) if tag.get('name')]

        return {
            'id': video_id,
            'url': audio_url,

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Check the slug resolves at play.fm in a browser
  2. If all PlayFM URLs fail, the service/API is likely dead or changed — update yt-dlp and check extractor status
  3. Search for the mix/recording under a different slug (title-based) on the site
Defensive patterns

Strategy: try-catch

Try / catch

try:
    info = ydl.extract_info(url)
except ExtractorError as e:
    if e.expected and 'PlayFM returned error' in str(e):
        log.info('PlayFM API rejected slug %s', slug)

Prevention

When it happens

Trigger: GET http://v2api.play.fm/recordings/slug/<slug> returning {'error': {'message': ...}}: unknown/deleted slug, or the v2 API rejecting the request shape.

Common situations: play.fm shut down or restructured its API (the service has been unstable), making every slug error; deleted recordings; slug typos from hand-edited URLs.

Related errors


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