ytdl-org/youtube-dl · error · ExtractorError
%s said: %s
Error message
%s said: %s
What it means
Thrown by the LiTV extractor when the vod/getMainUrl API call succeeds HTTP-wise but the returned JSON lacks a 'fullpath' key and instead carries an 'errorMessage'. It is marked expected=True, meaning it represents a normal, user-facing service refusal (e.g. expired asset, member-only content) rather than a bug in youtube-dl. The '%s said: %s' pattern prefixes the extractor name (LiTV) with the raw service message so the user sees exactly what the provider replied.
Source
Thrown at youtube_dl/extractor/litv.py:124
r'uiHlsUrl\s*=\s*testBackendData\(([^;]+)\);',
webpage, 'video data', default='{}'), video_id)
if not video_data:
payload = {
'assetId': program_info['assetId'],
'watchDevices': program_info['watchDevices'],
'contentType': program_info['contentType'],
}
video_data = self._download_json(
'https://www.litv.tv/vod/getMainUrl', video_id,
data=json.dumps(payload).encode('utf-8'),
headers={'Content-Type': 'application/json'})
if not video_data.get('fullpath'):
error_msg = video_data.get('errorMessage')
if error_msg == 'vod.error.outsideregionerror':
self.raise_geo_restricted('This video is available in Taiwan only')
if error_msg:
raise ExtractorError('%s said: %s' % (self.IE_NAME, error_msg), expected=True)
raise ExtractorError('Unexpected result from %s' % self.IE_NAME)
formats = self._extract_m3u8_formats(
video_data['fullpath'], video_id, ext='mp4',
entry_protocol='m3u8_native', m3u8_id='hls')
for a_format in formats:
# LiTV HLS segments doesn't like compressions
a_format.setdefault('http_headers', {})['Youtubedl-no-compression'] = True
title = program_info['title'] + program_info.get('secondaryMark', '')
description = program_info.get('description')
thumbnail = program_info.get('imageFile')
categories = [item['name'] for item in program_info.get('category', [])]
episode = int_or_none(program_info.get('episode'))
return {
'id': video_id,
'formats': formats,View on GitHub (pinned to 956b8c5855)
Solutions
- Read the embedded service message; it is LiTV's own text and names the exact refusal reason (expired, member-only, removed).
- If the message indicates region blocking, supply a Taiwan IP/proxy via --proxy or --geo-verification-proxy instead of retrying directly.
- If content is member-only, log in with the appropriate account cookies (--add-header 'Cookie: ...').
- If the message looks like a schema change (unrecognized text), report the video URL to the youtube-dl issue tracker so the LiTV extractor can be updated.
Defensive patterns
Strategy: try-catch
Type guard
def is_litv_error_payload(video_data):
return isinstance(video_data, dict) and not video_data.get('fullpath') and bool(video_data.get('errorMessage')) Try / catch
try:
info = ydl.extract_info(url, download=False)
except ExtractorError as e:
if 'LiTV said:' in str(e):
reason = str(e).split('said:', 1)[1].strip() # service's own message; act on it (geo, membership, expiry)
else:
raise Prevention
- Pre-check video availability in a Taiwan-located browser session before batching.
- Keep account cookies current when downloading member-only LiTV content.
- Wrap batch jobs to record the embedded service message per id instead of aborting the whole run.
When it happens
Trigger: POST to https://www.litv.tv/vod/getMainUrl with the contentType payload returns JSON without 'fullpath' but with a non-empty 'errorMessage'. Any errorMessage other than 'vod.error.outsideregionerror' (which is converted to a geo-restriction error just above) reaches this raise.
Common situations: Requesting a drama/episode that is no longer licensed, member-only content without a subscription cookie, or a video_id that LiTV no longer serves. Also hit when LiTV changes its API response shape so 'fullpath' is renamed, leaving only an error field.
Related errors
- Invalid url for track %d of album url %s
- message
- This video is DRM protected.
- Unable to download video %s
- lynda returned error: %s
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/ed9fb9d70d5bbc08.
Report an issue: GitHub.