{"record":{"id":"fd6b276ea0d708f6","repo":"ytdl-org/youtube-dl","slug":"course-s-does-not-exist","errorCode":null,"errorMessage":"Course %s does not exist","messagePattern":"Course (.+?) does not exist","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/lynda.py","lineNumber":308,"sourceCode":"        course = self._download_json(\n            'https://www.lynda.com/ajax/player?courseId=%s&type=course' % course_id,\n            course_id, 'Downloading course JSON', fatal=False)\n\n        if not course:\n            webpage = self._download_webpage(url, course_id)\n            entries = [\n                self.url_result(\n                    item_template % video_id, ie=LyndaIE.ie_key(),\n                    video_id=video_id)\n                for video_id in re.findall(\n                    r'data-video-id=[\"\\'](\\d+)', webpage)]\n            return self.playlist_result(\n                entries, course_id,\n                self._og_search_title(webpage, fatal=False),\n                self._og_search_description(webpage))\n\n        if course.get('Status') == 'NotFound':\n            raise ExtractorError(\n                'Course %s does not exist' % course_id, expected=True)\n\n        unaccessible_videos = 0\n        entries = []\n\n        # Might want to extract videos right here from video['Formats'] as it seems 'Formats' is not provided\n        # by single video API anymore\n\n        for chapter in course['Chapters']:\n            for video in chapter.get('Videos', []):\n                if video.get('HasAccess') is False:\n                    unaccessible_videos += 1\n                    continue\n                video_id = video.get('ID')\n                if video_id:\n                    entries.append({\n                        '_type': 'url_transparent',\n                        'url': item_template % video_id,","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/lynda.py#L290-L326","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# Cheap pre-flight: confirm the course page resolves before extraction\nimport urllib.request\nreq = urllib.request.Request(course_url, method='HEAD', headers={'User-Agent': 'Mozilla/5.0'})\nassert urllib.request.urlopen(req).status == 200, 'Course URL unreachable'","typeGuard":"def course_not_found(course_json):\n    return isinstance(course_json, dict) and course_json.get('Status') == 'NotFound'","tryCatchPattern":"try:\n    playlist = ydl.extract_info(course_url, download=False)\nexcept ExtractorError as e:\n    if 'does not exist' in str(e):\n        drop_course_from_queue(course_url)  # dead id; remove permanently\n    else:\n        raise","preventionTips":["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."],"tags":["playlist","not-found","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}