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

  1. Open the course URL in a browser to confirm it still exists.
  2. Search lynda.com for the course title and use the fresh URL (ids change when courses are re-published).
  3. If the course moved to LinkedIn Learning, use the linkedin.com URL with the appropriate extractor instead.
  4. 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

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


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/fd6b276ea0d708f6. Report an issue: GitHub.