{"record":{"id":"3f37db24a31364e3","repo":"ytdl-org/youtube-dl","slug":"lecture-s-is-not-a-video","errorCode":null,"errorMessage":"Lecture %s is not a video","messagePattern":"Lecture (.+?) is not a video","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"warning","filePath":"youtube_dl/extractor/udemy.py","lineNumber":238,"sourceCode":"\n        try:\n            lecture = self._download_lecture(course_id, lecture_id)\n        except ExtractorError as e:\n            # Error could possibly mean we are not enrolled in the course\n            if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:\n                self._enroll_course(url, webpage, course_id)\n                lecture = self._download_lecture(course_id, lecture_id)\n            else:\n                raise\n\n        title = lecture['title']\n        description = lecture.get('description')\n\n        asset = lecture['asset']\n\n        asset_type = asset.get('asset_type') or asset.get('assetType')\n        if asset_type != 'Video':\n            raise ExtractorError(\n                'Lecture %s is not a video' % lecture_id, expected=True)\n\n        stream_url = asset.get('stream_url') or asset.get('streamUrl')\n        if stream_url:\n            youtube_url = self._search_regex(\n                r'(https?://www\\.youtube\\.com/watch\\?v=.*)', stream_url, 'youtube URL', default=None)\n            if youtube_url:\n                return self.url_result(youtube_url, 'Youtube')\n\n        video_id = compat_str(asset['id'])\n        thumbnail = asset.get('thumbnail_url') or asset.get('thumbnailUrl')\n        duration = float_or_none(asset.get('data', {}).get('duration'))\n\n        subtitles = {}\n        automatic_captions = {}\n\n        formats = []\n","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/udemy.py#L220-L256","documentation":"Raised by UdemyIE._real_extract when the lecture's asset type is not 'Video' — e.g. 'Article', 'Quiz', 'Presentation', or 'Pdf' assets have no media stream to extract. Expected error identifying the lecture id; it protects the downstream code that assumes stream_url/media assets.","triggerScenarios":"Extracting a lecture URL whose lecture['asset']['asset_type'] (or assetType) is anything other than the literal 'Video' — article lectures, quizzes, coding exercises, downloadable attachments.","commonSituations":"Batch-downloading a whole course where most sections mix video lectures with reading assignments and quizzes; curriculum restructured to articles.","solutions":["Skip non-video lectures in your script by catching this expected error per lecture.","Filter the course curriculum JSON by asset_type == 'Video' before enqueueing lecture URLs.","For article lectures, fetch the HTML body via Udemy's API or scrape the page directly.","Handle attachments separately if your tool supports them (yt-dlp marks these lectures with _type 'url' style fallbacks in some versions)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"curriculum = udemy_api_get('/courses/%s/subscriber-curriculum-items/' % course_id)\nfor item in curriculum['results']:\n    asset = item.get('asset') or {}\n    if (asset.get('asset_type') or asset.get('assetType')) != 'Video':\n        continue  # skip articles/quizzes before extracting","typeGuard":"def is_video_lecture(lecture: dict) -> bool:\n    asset = lecture.get('asset') or {}\n    return (asset.get('asset_type') or asset.get('assetType')) == 'Video'","tryCatchPattern":"for lecture_url in course_lecture_urls:\n    try:\n        ydl.extract_info(lecture_url)\n    except ExtractorError as e:\n        if 'is not a video' in str(e):\n            continue  # article/quiz lecture — expected in mixed courses\n        else:\n            raise","preventionTips":["Filter the curriculum JSON by asset_type == 'Video' before enqueueing lecture URLs.","Treat this expected error as a skip signal, not a failure, in course-mirror scripts."],"tags":["udemy","asset-type","filtering","course"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}