{"record":{"id":"fc2140fb98294a74","repo":"ytdl-org/youtube-dl","slug":"course-s-is-not-free-you-have-to-pay-for-it-befo","errorCode":null,"errorMessage":"Course %s is not free. You have to pay for it before you can download. Use this URL to confirm purchase: %s","messagePattern":"Course (.+?) is not free\\. You have to pay for it before you can download\\. Use this URL to confirm purchase: (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/udemy.py","lineNumber":93,"sourceCode":"                r'ng-init=[\"\\'].*\\bcourse=({.+?})[;\"\\']',\n                webpage, 'course', default='{}')),\n            video_id, fatal=False) or {}\n        course_id = course.get('id') or self._search_regex(\n            [\n                r'data-course-id=[\"\\'](\\d+)',\n                r'&quot;courseId&quot;\\s*:\\s*(\\d+)'\n            ], webpage, 'course id')\n        return course_id, course.get('title')\n\n    def _enroll_course(self, base_url, webpage, course_id):\n        def combine_url(base_url, url):\n            return compat_urlparse.urljoin(base_url, url) if not url.startswith('http') else url\n\n        checkout_url = unescapeHTML(self._search_regex(\n            r'href=([\"\\'])(?P<url>(?:https?://(?:www\\.)?udemy\\.com)?/(?:payment|cart)/checkout/.+?)\\1',\n            webpage, 'checkout url', group='url', default=None))\n        if checkout_url:\n            raise ExtractorError(\n                'Course %s is not free. You have to pay for it before you can download. '\n                'Use this URL to confirm purchase: %s'\n                % (course_id, combine_url(base_url, checkout_url)),\n                expected=True)\n\n        enroll_url = unescapeHTML(self._search_regex(\n            r'href=([\"\\'])(?P<url>(?:https?://(?:www\\.)?udemy\\.com)?/course/subscribe/.+?)\\1',\n            webpage, 'enroll url', group='url', default=None))\n        if enroll_url:\n            webpage = self._download_webpage(\n                combine_url(base_url, enroll_url),\n                course_id, 'Enrolling in the course',\n                headers={'Referer': base_url})\n            if '>You have enrolled in' in webpage:\n                self.to_screen('%s: Successfully enrolled in the course' % course_id)\n\n    def _download_lecture(self, course_id, lecture_id):\n        return self._download_json(","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/udemy.py#L75-L111","documentation":"Raised by UdemyIE._enroll_course when the course page HTML exposes a /(payment|cart)/checkout/ link — the course is paid and not enrolled, so lecture content cannot be fetched. The error embeds the full checkout URL so the user can complete the purchase in a browser. Expected error.","triggerScenarios":"Extracting an Udemy lecture while not enrolled: _extract_course_info loads the page, and the checkout-URL regex matches an href to /payment/checkout/ or /cart/checkout/, triggering the raise before the free /course/subscribe/ enroll path is tried.","commonSituations":"Paid Udemy courses without a logged-in enrolled account, logged-out users hitting paywalled lecture pages, free coupon not applied (must visit the coupon URL first to enroll).","solutions":["Open the checkout URL from the error message in a browser, buy the course, then export cookies and rerun with --cookies.","If a free coupon exists, enroll via the coupon link in the browser first so /course/subscribe/ is used, then pass those cookies.","Log into Udemy in a browser and pass --username/--password or --cookies so _enroll_course sees your entitlement.","Choose a genuinely free course/lecture."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import requests\nhtml = requests.get(lecture_url, cookies=udemy_cookies).text\nif '/payment/checkout/' in html or '/cart/checkout/' in html:\n    needs_purchase(course_id)","typeGuard":"def udemy_needs_checkout(html: str) -> bool:\n    return '/payment/checkout/' in html or '/cart/checkout/' in html","tryCatchPattern":"try:\n    ydl.extract_info(lecture_url)\nexcept ExtractorError as e:\n    if 'not free' in str(e):\n        checkout = str(e).split('purchase: ')[-1].strip()\n        record_checkout_url(course_id, checkout)\n    else:\n        raise","preventionTips":["Enroll (including via free coupons) in a browser before downloading; then export cookies.","Reuse the checkout URL embedded in the error message to complete purchase instead of guessing."],"tags":["udemy","paywall","enrollment","cookies","login"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}