ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

Raised by the VVVVID extractor's _download_info helper when the on-demand API (https://www.vvvvid.it/vvvvid/ondemand/...) returns a JSON object with result == 'error'. The API includes a message field which is forwarded with the extractor name; typical causes are geo-restriction to Italy, expired episodes, or invalid show/season IDs.

Source

Thrown at youtube_dl/extractor/vvvvid.py:102

    def _real_initialize(self):
        self._conn_id = self._download_json(
            'https://www.vvvvid.it/user/login',
            None, headers=self.geo_verification_headers())['data']['conn_id']

    def _download_info(self, show_id, path, video_id, fatal=True, query=None):
        q = {
            'conn_id': self._conn_id,
        }
        if query:
            q.update(query)
        response = self._download_json(
            'https://www.vvvvid.it/vvvvid/ondemand/%s/%s' % (show_id, path),
            video_id, headers=self.geo_verification_headers(), query=q, fatal=fatal)
        if not (response or fatal):
            return
        if response.get('result') == 'error':
            raise ExtractorError('%s said: %s' % (
                self.IE_NAME, response['message']), expected=True)
        return response['data']

    def _extract_common_video_info(self, video_data):
        return {
            'thumbnail': video_data.get('thumbnail'),
            'episode_id': str_or_none(video_data.get('id')),
        }

    def _real_extract(self, url):
        show_id, season_id, video_id = re.match(self._VALID_URL, url).groups()

        response = self._download_info(
            show_id, 'season/%s' % season_id,
            video_id, query={'video_id': video_id})

        vid = int(video_id)
        video_data = list(filter(

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Read the forwarded 'VVVVID said: ...' message for the exact cause.
  2. If geo-related, use an Italian IP or accept the content is unavailable in your region.
  3. Verify the show/season/video IDs in the URL against the site.
  4. Pass cookies with --cookies if the content requires authentication.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    info = ydl.extract_info(url)
except ExtractorError as e:
    if str(e).startswith('VVVVID said:'):
        msg = str(e).split('said:', 1)[1].strip()
        if 'geo' in msg.lower():
            mark_geo_blocked(url)
        else:
            log_skip(url, msg)
    else:
        raise

Prevention

When it happens

Trigger: Any VVVVID API call whose response JSON has response['result'] == 'error'; _download_info is used for show, season, and video metadata, so bad IDs or unavailable content produce it.

Common situations: Accessing VVVVID (Italian streaming service) from outside Italy; following links to episodes whose rights have lapsed; malformed URLs where season_id or video_id does not exist.

Related errors


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