yt-dlp/yt-dlp · error · ExtractorError

{error_desc}

Error message

{error_desc}

What it means

The wat.tv (TVA) extractor reads the media object from the delivery API; any error_desc there is a playback refusal. GEOBLOCKED is mapped to raise_geo_restricted, DELIVERY_ERROR with delivery code 403/500 to a DRM report, and every other error surfaces its text verbatim as an expected ExtractorError.

Source

Thrown at yt_dlp/extractor/wat.py:83

        # videos, we don't need them
        # video_data = self._download_json(
        #     'http://www.wat.tv/interface/contentv4s/' + video_id, video_id)
        video_data = self._download_json(
            'https://mediainfo.tf1.fr/mediainfocombo/' + video_id,
            video_id, query={'pver': '5010000'})
        video_info = video_data['media']

        error_desc = video_info.get('error_desc')
        if error_desc:
            error_code = video_info.get('error_code')
            if error_code == 'GEOBLOCKED':
                self.raise_geo_restricted(error_desc, video_info.get('geoList'))
            elif error_code == 'DELIVERY_ERROR':
                if traverse_obj(video_data, ('delivery', 'code')) in (403, 500):
                    self.report_drm(video_id)
                error_desc = join_nonempty(
                    error_desc, traverse_obj(video_data, ('delivery', 'error', {str})), delim=': ')
            raise ExtractorError(error_desc, expected=True)

        title = video_info['title']

        formats = []
        subtitles = {}

        def extract_formats(manifest_urls):
            for f, f_url in manifest_urls.items():
                if not f_url:
                    continue
                if f in ('dash', 'mpd'):
                    fmts, subs = self._extract_mpd_formats_and_subtitles(
                        f_url.replace('://das-q1.tf1.fr/', '://das-q1-ssl.tf1.fr/'),
                        video_id, mpd_id='dash', fatal=False)
                elif f == 'hls':
                    fmts, subs = self._extract_m3u8_formats_and_subtitles(
                        f_url, video_id, 'mp4',
                        'm3u8_native', m3u8_id='hls', fatal=False)

View on GitHub (pinned to 81ecd58b13)

Solutions

  1. Read the surfaced error text: geo errors require an authorized (Canadian) network or a different source
  2. If the cause was DRM (delivery code 403/500 reported as DRM), yt-dlp cannot download it - there is no workaround
  3. Confirm the video still plays on wat.tv in a browser; dead links legitimately produce this
  4. Update yt-dlp in case the error mapping improved
Defensive patterns

Strategy: try-catch

Type guard

from yt_dlp.utils import GeoRestrictedError

def classify_wat_error(exc: Exception) -> str:
    if isinstance(exc, GeoRestrictedError):
        return 'geo'
    if isinstance(exc, ExtractorError) and 'DRM' in str(exc):
        return 'drm'
    if isinstance(exc, ExtractorError) and exc.expected:
        return 'api'
    return 'unknown'

Try / catch

try:
    info = ydl.extract_info(wat_url, download=False)
except DownloadError as e:
    if isinstance(getattr(e, 'exc_info', (None, None))[1], GeoRestrictedError) or 'geo' in str(e).lower():
        route_via_canadian_proxy()
    elif 'DRM' in str(e):
        skip_permanently(wat_url)  # no workaround exists
    else:
        check_if_link_is_dead(wat_url)

Prevention

When it happens

Trigger: Extracting a wat.tv/video URL whose media JSON contains error_desc: geoblocking outside authorized regions, DRM-protected delivery (delivery.code 403 or 500), removed videos, or platform-specific delivery errors.

Common situations: Watching French-Canadian content from outside Canada; DRM'd TVA+ simulcast content; dead or expired links.

Related errors


AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22). Data as JSON: /api/errors/ee13ebe26c95f335. Report an issue: GitHub.