ytdl-org/youtube-dl · error · ExtractorError
Letv cloud returned an unknown error
Error message
Letv cloud returned an unknown error
What it means
Raised by the Letv Cloud extractor when the gpc.php playJson response has neither 'data', nor 'message', nor a usable 'code' — a completely unrecognized error shape. It is expected=True but signals the extractor cannot interpret the API response at all, which often means an API contract change rather than a content problem.
Source
Thrown at youtube_dl/extractor/leeco.py:329
'ran': compat_str(timestamp),
}
self.sign_data(data)
return self._download_json(
'http://api.letvcloud.com/gpc.php?' + compat_urllib_parse_urlencode(data),
media_id, 'Downloading playJson data for type %s' % cf)
play_json = get_play_json(cf, time.time())
# The server time may be different from local time
if play_json.get('code') == 10071:
play_json = get_play_json(cf, play_json['timestamp'])
if not play_json.get('data'):
if play_json.get('message'):
raise ExtractorError('Letv cloud said: %s' % play_json['message'], expected=True)
elif play_json.get('code'):
raise ExtractorError('Letv cloud returned error %d' % play_json['code'], expected=True)
else:
raise ExtractorError('Letv cloud returned an unknown error')
def b64decode(s):
return compat_b64decode(s).decode('utf-8')
formats = []
for media in play_json['data']['video_info']['media'].values():
play_url = media['play_url']
url = b64decode(play_url['main_url'])
decoded_url = b64decode(url_basename(url))
formats.append({
'url': url,
'ext': determine_ext(decoded_url),
'format_id': str_or_none(play_url.get('vtype')),
'format_note': str_or_none(play_url.get('definition')),
'width': int_or_none(play_url.get('vwidth')),
'height': int_or_none(play_url.get('vheight')),
})
View on GitHub (pinned to 956b8c5855)
Solutions
- Update youtube-dl / switch to yt-dlp — unknown-shape responses usually mean an API change already fixed upstream
- Fetch the gpc.php URL manually with the same uu/vu to inspect what is actually returned
- If the service is dead in your region or entirely, use an alternative source for the content
- Report the response body upstream so the extractor can be taught the new shape
Defensive patterns
Strategy: retry
Validate before calling
import json, urllib.request
def letv_api_returns_json(uu, vu):
# smoke-test the gpc.php endpoint shape before running the extractor
url = 'http://api.letvcloud.com/gpc.php?uu=%s&vu=%s&cf=flash' % (uu, vu)
try:
json.load(urllib.request.urlopen(url, timeout=10))
return True
except (ValueError, urllib.error.URLError):
return False Try / catch
try:
ydl.extract_info(url)
except ExtractorError as e:
if 'unknown error' in str(e):
update_extractor_or_switch_to_ytdlp() # response shape changed upstream
else:
raise Prevention
- Smoke-test the API endpoint shape before batch runs
- Prefer yt-dlp, which tracks API changes faster for niche extractors
When it happens
Trigger: Letv Cloud extraction where gpc.php returns JSON with none of the expected keys (for example an HTML error page parsed as JSON, an empty object, or a new response schema after an API update).
Common situations: Letv Cloud API endpoints being deprecated or restructured; CDN edge responses (maintenance/captcha pages) returned instead of JSON; very old youtube-dl versions against a changed API; network middleboxes mangling responses.
Related errors
- Letv cloud said: %s
- Letv cloud returned error %d
- Invalid URL: %s
- Invalid rendition field.
- Could not find video title
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/b710b518f7cb5709.
Report an issue: GitHub.