ytdl-org/youtube-dl · error · ExtractorError
Course %s does not exist
Error message
Course %s does not exist
What it means
Raised by the Lynda course playlist extractor when the course API responds with Status == 'NotFound', meaning the requested course id does not exist on lynda.com. Expected=True, so it is a clean 'no such resource' signal rather than a parsing crash. The course id from the URL is embedded in the message.
Source
Thrown at youtube_dl/extractor/lynda.py:308
course = self._download_json(
'https://www.lynda.com/ajax/player?courseId=%s&type=course' % course_id,
course_id, 'Downloading course JSON', fatal=False)
if not course:
webpage = self._download_webpage(url, course_id)
entries = [
self.url_result(
item_template % video_id, ie=LyndaIE.ie_key(),
video_id=video_id)
for video_id in re.findall(
r'data-video-id=["\'](\d+)', webpage)]
return self.playlist_result(
entries, course_id,
self._og_search_title(webpage, fatal=False),
self._og_search_description(webpage))
if course.get('Status') == 'NotFound':
raise ExtractorError(
'Course %s does not exist' % course_id, expected=True)
unaccessible_videos = 0
entries = []
# Might want to extract videos right here from video['Formats'] as it seems 'Formats' is not provided
# by single video API anymore
for chapter in course['Chapters']:
for video in chapter.get('Videos', []):
if video.get('HasAccess') is False:
unaccessible_videos += 1
continue
video_id = video.get('ID')
if video_id:
entries.append({
'_type': 'url_transparent',
'url': item_template % video_id,View on GitHub (pinned to 956b8c5855)
Solutions
- Open the course URL in a browser to confirm it still exists.
- Search lynda.com for the course title and use the fresh URL (ids change when courses are re-published).
- If the course moved to LinkedIn Learning, use the linkedin.com URL with the appropriate extractor instead.
- Update youtube-dl so the latest course-endpoint mapping is in use.
Defensive patterns
Strategy: try-catch
Validate before calling
# Cheap pre-flight: confirm the course page resolves before extraction
import urllib.request
req = urllib.request.Request(course_url, method='HEAD', headers={'User-Agent': 'Mozilla/5.0'})
assert urllib.request.urlopen(req).status == 200, 'Course URL unreachable' Type guard
def course_not_found(course_json):
return isinstance(course_json, dict) and course_json.get('Status') == 'NotFound' Try / catch
try:
playlist = ydl.extract_info(course_url, download=False)
except ExtractorError as e:
if 'does not exist' in str(e):
drop_course_from_queue(course_url) # dead id; remove permanently
else:
raise Prevention
- Refresh course URLs from lynda.com/LinkedIn Learning search rather than reusing bookmarked numeric ids.
- Map retired lynda.com courses to their linkedin.com equivalents upfront.
When it happens
Trigger: GET of the lynda.com course endpoint (e.g. /courses/{course_id}/courses or the player API) returns JSON with course['Status'] == 'NotFound'. URLs whose numeric course id is mistyped or whose course was deleted hit this path.
Common situations: Typo in the numeric course id in the URL; course unpublished or removed by Lynda/LinkedIn Learning; migration of content to linkedin.com making old lynda.com ids stale; bookmarked links from search engines pointing at retired courses.
Related errors
- That clip does not exist.
- %s
- Video %s does not exist
- %s: No songs found, try using proxy
- The video is not found.
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/fd6b276ea0d708f6.
Report an issue: GitHub.