ytdl-org/youtube-dl · error · ExtractorError
Unable to find video URL
Error message
Unable to find video URL
What it means
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.
Source
Thrown at youtube_dl/extractor/teachable.py:176
self._login(site)
prefixed = url.startswith(self._URL_PREFIX)
if prefixed:
url = url[len(self._URL_PREFIX):]
webpage = self._download_webpage(url, video_id)
wistia_urls = WistiaIE._extract_urls(webpage)
if not wistia_urls:
if any(re.search(p, webpage) for p in (
r'class=["\']lecture-contents-locked',
r'>\s*Lecture contents locked',
r'id=["\']lecture-locked',
# https://academy.tailoredtutors.co.uk/courses/108779/lectures/1955313
r'class=["\'](?:inner-)?lesson-locked',
r'>LESSON LOCKED<')):
self.raise_login_required('Lecture contents locked')
raise ExtractorError('Unable to find video URL')
title = self._og_search_title(webpage, default=None)
chapter = None
chapter_number = None
section_item = self._search_regex(
r'(?s)(?P<li><li[^>]+\bdata-lecture-id=["\']%s[^>]+>.+?</li>)' % video_id,
webpage, 'section item', default=None, group='li')
if section_item:
chapter_number = int_or_none(self._search_regex(
r'data-ss-position=["\'](\d+)', section_item, 'section id',
default=None))
if chapter_number is not None:
sections = []
for s in re.findall(
r'(?s)<div[^>]+\bclass=["\']section-title[^>]+>(.+?)</div>', webpage):
section = strip_or_none(clean_html(s))
if not section:View on GitHub (pinned to 956b8c5855)
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.
Example fix
# before: lecture uses a non-Wistia embed # youtube-dlc https://school.teachable.com/courses/x/lectures/123 # after: extract embed URL from page source, then use its extractor # view-source -> find iframe src, e.g. https://www.youtube.com/embed/XYZ # youtube-dl https://www.youtube.com/watch?v=XYZ
Defensive patterns
Strategy: fallback
Validate before calling
# Check for a playable embed before invoking the extractor
html = ydl.urlopen(url).read().decode('utf-8', 'replace')
if 'wistia' not in html.lower():
print('no Wistia embed found; lecture may use another provider or require login') Try / catch
try:
info = ydl.extract_info(url)
except ExtractorError as e:
if 'Unable to find video URL' in str(e):
info = try_with_cookies(url) or extract_embed_manually(html)
if hasattr(e, 'exc_info') and 'Lecture contents locked' in str(e):
raise # needs login, not a markup issue
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to log in
- Unable to log in
- Unable to log in
- Unable to login: %s asks you to accept new Privacy Policy. G
- Unable to login: %s
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/5e3f76612b806496.
Report an issue: GitHub.