yt-dlp/yt-dlp · error · ExtractorError
{msg['detail']}
Error message
{msg['detail']} What it means
Viidea (lecture-capture platform) extractor surfaces the API's own error text: when the lecture metadata request ({livepipe}/site/api/lecture/{id}?format=json) returns HTTP 403, the JSON response's 'detail' field is re-raised as the error message with expected=True. Whatever the server says — password required, lecture unpublished, permissions — becomes the user-visible message.
Source
Thrown at yt_dlp/extractor/viidea.py:136
cfg = self._parse_json(self._search_regex(
[r'cfg\s*:\s*({.+?})\s*,\s*[\da-zA-Z_]+\s*:\s*\(?\s*function',
r'cfg\s*:\s*({[^}]+})'],
webpage, 'cfg'), lecture_slug, js_to_json)
lecture_id = str(cfg['obj_id'])
base_url = self._proto_relative_url(cfg['livepipe'], 'http:')
try:
lecture_data = self._download_json(
f'{base_url}/site/api/lecture/{lecture_id}?format=json',
lecture_id)['lecture'][0]
except ExtractorError as e:
if isinstance(e.cause, HTTPError) and e.cause.status == 403:
msg = self._parse_json(
e.cause.response.read().decode('utf-8'), lecture_id)
raise ExtractorError(msg['detail'], expected=True)
raise
lecture_info = {
'id': lecture_id,
'display_id': lecture_slug,
'title': lecture_data['title'],
'timestamp': parse_iso8601(lecture_data.get('time')),
'description': lecture_data.get('description_wiki'),
'thumbnail': lecture_data.get('thumb'),
}
playlist_entries = []
lecture_type = lecture_data.get('type')
parts = [str(video) for video in cfg.get('videos', [])]
if parts:
multipart = len(parts) > 1
def extract_part(part_id):View on GitHub (pinned to 81ecd58b13)
Solutions
- Read the detail text — it states the server's reason (locked, unpublished, unauthorized).
- If the portal requires login, authenticate in a browser, export cookies, and pass --cookies.
- Confirm the lecture is playable in a browser while logged in; if not, it cannot be downloaded either.
- Update yt-dlp in case the API contract changed.
Defensive patterns
Strategy: try-catch
Try / catch
try:
info = ydl.extract_info(url, download=True)
except DownloadError as e:
if '[viidea]' in str(e):
# e.message is the server's own 'detail' text (locked/unpublished/unauthorized)
log_warning(f'lecture API refused: {e}')
else:
raise Prevention
- Check the lecture plays in a browser (logged in) before batch downloading.
- Export portal cookies when the institution requires a session.
- Schedule downloads after lectures are published, not before.
When it happens
Trigger: The lecture API returns 403 with a JSON body containing a 'detail' key — e.g. the lecture is not yet published, is instructor-only, or the institution disabled anonymous access to the recording.
Common situations: Students downloading lectures before they are made public, institutional portals that require an authenticated session, or lectures whose availability window has closed.
Related errors
- {error['error_description']}
- {api_message_or_error_code}
- {msg}
- {site} said: {webpage}
- _parse_json(e.cause.response.read().decode(), video_id)['mes
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/dbdfc41682edb527.
Report an issue: GitHub.