{"record":{"id":"5e3f76612b806496","repo":"ytdl-org/youtube-dl","slug":"unable-to-find-video-url","errorCode":null,"errorMessage":"Unable to find video URL","messagePattern":"Unable to find video URL","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/teachable.py","lineNumber":176,"sourceCode":"        self._login(site)\n\n        prefixed = url.startswith(self._URL_PREFIX)\n        if prefixed:\n            url = url[len(self._URL_PREFIX):]\n\n        webpage = self._download_webpage(url, video_id)\n\n        wistia_urls = WistiaIE._extract_urls(webpage)\n        if not wistia_urls:\n            if any(re.search(p, webpage) for p in (\n                    r'class=[\"\\']lecture-contents-locked',\n                    r'>\\s*Lecture contents locked',\n                    r'id=[\"\\']lecture-locked',\n                    # https://academy.tailoredtutors.co.uk/courses/108779/lectures/1955313\n                    r'class=[\"\\'](?:inner-)?lesson-locked',\n                    r'>LESSON LOCKED<')):\n                self.raise_login_required('Lecture contents locked')\n            raise ExtractorError('Unable to find video URL')\n\n        title = self._og_search_title(webpage, default=None)\n\n        chapter = None\n        chapter_number = None\n        section_item = self._search_regex(\n            r'(?s)(?P<li><li[^>]+\\bdata-lecture-id=[\"\\']%s[^>]+>.+?</li>)' % video_id,\n            webpage, 'section item', default=None, group='li')\n        if section_item:\n            chapter_number = int_or_none(self._search_regex(\n                r'data-ss-position=[\"\\'](\\d+)', section_item, 'section id',\n                default=None))\n            if chapter_number is not None:\n                sections = []\n                for s in re.findall(\n                        r'(?s)<div[^>]+\\bclass=[\"\\']section-title[^>]+>(.+?)</div>', webpage):\n                    section = strip_or_none(clean_html(s))\n                    if not section:","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/teachable.py#L158-L194","documentation":"Raised by TeachableIE._real_extract when the lecture page contains no Wistia embed URLs (WistiaIE._extract_urls returns empty) AND none of the 'locked' markers (lecture-contents-locked, Lecture contents locked, lecture-locked, lesson-locked, LESSON LOCKED) are present. Not marked expected=True. It means the page loaded but the extractor found neither a player it recognizes nor a known lock screen.","triggerScenarios":"Extracting /courses/<course>/lectures/<id> on a Teachable site where the video is embedded via a provider other than Wistia, the lecture has only attachments/text, or the page markup changed so the Wistia URL pattern no longer matches.","commonSituations":"Teachable schools embedding with YouTube/Vimeo/Wistia-new-embed after platform updates; lectures that are quizzes or PDF-only; enrolling changes that render lecture HTML differently for enrolled vs preview users.","solutions":["Open the lecture in a browser (logged in) and check what hosts the video; if it is not Wistia, use the matching extractor for the embed URL found in the page/network tab.","Ensure you are authenticated: pass --username/--password or --cookies — some lectures only render the player for enrolled users, without the locked markers this extractor checks.","Upgrade to yt-dlp, whose Teachable/Wistia handling is actively maintained for new embed formats.","If the lecture genuinely has no video (text/attachment only), there is nothing to download; pick an actual video lecture URL."],"exampleFix":"# before: lecture uses a non-Wistia embed\n# youtube-dlc https://school.teachable.com/courses/x/lectures/123\n# after: extract embed URL from page source, then use its extractor\n# view-source -> find iframe src, e.g. https://www.youtube.com/embed/XYZ\n# youtube-dl https://www.youtube.com/watch?v=XYZ","handlingStrategy":"fallback","validationCode":"# Check for a playable embed before invoking the extractor\nhtml = ydl.urlopen(url).read().decode('utf-8', 'replace')\nif 'wistia' not in html.lower():\n    print('no Wistia embed found; lecture may use another provider or require login')","typeGuard":null,"tryCatchPattern":"try:\n    info = ydl.extract_info(url)\nexcept ExtractorError as e:\n    if 'Unable to find video URL' in str(e):\n        info = try_with_cookies(url) or extract_embed_manually(html)\n    if hasattr(e, 'exc_info') and 'Lecture contents locked' in str(e):\n        raise  # needs login, not a markup issue\n    raise","preventionTips":["Authenticate (--cookies) before extracting Teachable lectures; some render players only when enrolled.","If lectures embed non-Wistia players, extract the iframe URL and use that provider's extractor.","Report markup changes upstream; yt-dlp tracks them faster."],"tags":["no-formats","login","site-change","teachable"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}