ytdl-org/youtube-dl · error · ExtractorError
No chapters found for course %s
Error message
No chapters found for course %s
What it means
Raised by the SafariCourseIE playlist extractor when the course JSON from the API has no 'chapters' key - there is nothing to enumerate into entries. Message interpolates the course id. Expected=True.
Source
Thrown at youtube_dl/extractor/safari.py:255
}, {
'url': 'https://www.oreilly.com/library/view/hadoop-fundamentals-livelessons/9780133392838/',
'only_matching': True,
}]
@classmethod
def suitable(cls, url):
return (False if SafariIE.suitable(url) or SafariApiIE.suitable(url)
else super(SafariCourseIE, cls).suitable(url))
def _real_extract(self, url):
course_id = self._match_id(url)
course_json = self._download_json(
'%s/book/%s/?override_format=%s' % (self._API_BASE, course_id, self._API_FORMAT),
course_id, 'Downloading course JSON')
if 'chapters' not in course_json:
raise ExtractorError(
'No chapters found for course %s' % course_id, expected=True)
entries = [
self.url_result(chapter, SafariApiIE.ie_key())
for chapter in course_json['chapters']]
course_title = course_json['title']
return self.playlist_result(entries, course_id, course_title)
View on GitHub (pinned to 956b8c5855)
Solutions
- Open the course page in a browser to confirm it still exists and contains video chapters.
- If it is a book (no video), there is nothing for youtube-dl to extract.
- Update youtube-dl in case the API response shape changed.
- If extracting single videos works, extract chapters individually instead of the whole course.
Defensive patterns
Strategy: validation
Validate before calling
# with the API accessible (same auth as the extractor)
def course_has_chapters(api_base, course_id, fmt):
import json, urllib.request
u = '%s/book/%s/?override_format=%s' % (api_base, course_id, fmt)
with urllib.request.urlopen(u, timeout=10) as r:
return 'chapters' in json.load(r) Try / catch
try:
ydl.extract_info(url)
except ExtractorError as e:
if 'No chapters found for course' in str(e):
skip(course_id) # retired course or non-video book
else:
raise Prevention
- Verify in a browser that the course exists and actually contains video chapters.
- Book-only (non-video) O'Reilly titles will always fail here - filter them before queueing.
- If single-video extraction works, fall back to per-chapter URLs.
When it happens
Trigger: Downloading a safari course URL (library/view/<course>) whose /book/<id>/ API response lacks 'chapters': retired courses, non-video books, or API format changes (override_format parameter).
Common situations: Courses delisted from O'Reilly learning; URLs for book-only (non-video) titles; API contract changes after O'Reilly deploys.
Related errors
- Unable to login: %s
- Course %s does not exist
- %s: No songs found, try using proxy
- QQ Music said: error %d in fetching playlist info
- Unable to log in
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/4c7a938bce437fb9.
Report an issue: GitHub.