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
- Read the surfaced error text: geo errors require an authorized (Canadian) network or a different source
- If the cause was DRM (delivery code 403/500 reported as DRM), yt-dlp cannot download it - there is no workaround
- Confirm the video still plays on wat.tv in a browser; dead links legitimately produce this
- 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
- Classify wat.tv failures by text: geo, DRM, and dead links need different handling
- Do not retry DRM or geoblocked items without changing network conditions
- Verify wat.tv links still play in a browser before queueing them
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
- Got empty response from playback API
- This video is either unavailable in your region or is DRM pr
- {message}
- {errors}
- MiniTV said: {resp["errors"][0]["message"]}
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/ee13ebe26c95f335.
Report an issue: GitHub.