ytdl-org/youtube-dl · error · ExtractorError

%s said: %s

Error message

%s said: %s

What it means

Raised by TeacherTubeIE when the video page contains a div whose class starts 'msgBox error'; the matched inner text is relayed as 'TeacherTube said: <error>' with expected=True. The site itself reports a problem for that video id before any metadata parsing happens.

Source

Thrown at youtube_dl/extractor/teachertube.py:55

            'ext': 'mp3',
            'title': 'PER ASPERA AD ASTRA',
            'description': 'RADIJSKA EMISIJA ZRAKOPLOVNE TEHNI?KE ?KOLE P',
        },
    }, {
        # unavailable video
        'url': 'http://www.teachertube.com/video/intro-video-schleicher-297790',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        webpage = self._download_webpage(url, video_id)

        error = self._search_regex(
            r'<div\b[^>]+\bclass=["\']msgBox error[^>]+>([^<]+)', webpage,
            'error', default=None)
        if error:
            raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True)

        title = self._html_search_meta('title', webpage, 'title', fatal=True)
        TITLE_SUFFIX = ' - TeacherTube'
        if title.endswith(TITLE_SUFFIX):
            title = title[:-len(TITLE_SUFFIX)].strip()

        description = self._html_search_meta('description', webpage, 'description')
        if description:
            description = description.strip()

        quality = qualities(['mp3', 'flv', 'mp4'])

        media_urls = re.findall(r'data-contenturl="([^"]+)"', webpage)
        media_urls.extend(re.findall(r'var\s+filePath\s*=\s*"([^"]+)"', webpage))
        media_urls.extend(re.findall(r'\'file\'\s*:\s*["\']([^"\']+)["\'],', webpage))

        formats = [
            {

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Read the relayed message — it is TeacherTube's own error text for that video.
  2. Verify the URL in a browser; if the video is gone, source it from the teacher's re-upload or the district's channel.
  3. For crawlers, catch this expected error and mark the link dead rather than retrying.
Defensive patterns

Strategy: try-catch

Validate before calling

html = ydl.urlopen(url).read().decode('utf-8', 'replace')
import re
m = re.search(r'<div\b[^>+\bclass=["\']msgBox error[^>]+>([^<]+)', html)
if m:
    print('TeacherTube reported:', m.group(1))

Try / catch

try:
    info = ydl.extract_info(url)
except ExtractorError as e:
    if e.expected and 'said:' in str(e):
        log.info('TeacherTube refused %s: %s', url, str(e))
        return None
    raise

Prevention

When it happens

Trigger: Extracting www.teachertube.com/video/.../<id> where the rendered page carries an error msgBox — typically removed/unavailable videos or server-side access errors.

Common situations: Videos deleted by the uploader or moderated off the platform; school-district content filters serving error pages; stale links in LMS courses.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/4bc00d536107f233. Report an issue: GitHub.