ytdl-org/youtube-dl · error · ExtractorError

%s returned error: %s

Error message

%s returned error: %s

What it means

Raised by ShahidIE._real_extract when the legacy v1_1 API (api.shahid.net/api/v1_1/<type>/<id>) returns a data payload containing an 'error' dict. All error values (typically message strings per error key) are newline-joined into one message prefixed with the extractor name. Expected=True, so it represents a server-reported content error such as 'not found' or 'not available in your region'.

Source

Thrown at youtube_dl/extractor/shahid.py:146

        self._sort_formats(formats)

        # video = self._call_api(
        #     'product/id', video_id, {
        #         'id': video_id,
        #         'productType': 'ASSET',
        #         'productSubType': page_type.upper()
        #     })['productModel']

        response = self._download_json(
            'http://api.shahid.net/api/v1_1/%s/%s' % (page_type, video_id),
            video_id, 'Downloading video JSON', query={
                'apiKey': 'sh@hid0nlin3',
                'hash': 'b2wMCTHpSmyxGqQjJFOycRmLSex+BpTK/ooxy6vHaqs=',
            })
        data = response.get('data', {})
        error = data.get('error')
        if error:
            raise ExtractorError(
                '%s returned error: %s' % (self.IE_NAME, '\n'.join(error.values())),
                expected=True)

        video = data[page_type]
        title = video['title']
        categories = [
            category['name']
            for category in video.get('genres', []) if 'name' in category]

        return {
            'id': video_id,
            'title': title,
            'description': video.get('description'),
            'thumbnail': video.get('thumbnailUrl'),
            'duration': int_or_none(video.get('duration')),
            'timestamp': parse_iso8601(video.get('referenceDate')),
            'categories': categories,
            'series': video.get('showTitle') or video.get('showName'),

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Verify the Shahid URL opens in a browser and note any 'content unavailable' notice.
  2. Search Shahid for the same title to get the current canonical episode URL (ids change when shows are re-listed).
  3. If region-locked, use a VPN matching the licensed region.
  4. Update youtube-dl/yt-dlp - newer versions drop the v1_1 call entirely and rely on the proxy API, avoiding this path.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    extract(url)
except ExtractorError as e:
    if e.expected and str(e).startswith('Shahid'):
        record_dead_link(url, str(e))
    else:
        raise

Prevention

When it happens

Trigger: Downloading the v1_1 video JSON with the hard-coded apiKey/hash query and receiving {'data': {'error': {...}}} - e.g. a deleted show/episode, an invalid or truncated video id, or a region-locked asset.

Common situations: Following dead/deprecated Shahid links whose playout succeeded but metadata 404s; URL typos after the last path segment; MBC regional licensing making an asset error out outside the licensed region; the v1_1 endpoint itself being retired in favor of the AWS proxy API.

Related errors


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