yt-dlp/yt-dlp · error · ExtractorError
This course episode is not yet available.
Error message
This course episode is not yet available.
What it means
Expected error raised by BilibiliCheeseBaseIE._extract_episode when the course episode's ep_status field equals -1. Cheese (pugv) courses publish episode metadata ahead of release; ep_status == -1 marks an episode that has not aired/been unlocked yet, so the extractor fails fast instead of calling the playurl API for media that cannot exist.
Source
Thrown at yt_dlp/extractor/bilibili.py:1202
webpage = self._download_webpage(url, ss_id)
metainfo = traverse_obj(
self._search_json(r'<script[^>]+type="application/ld\+json"[^>]*>', webpage, 'info', ss_id),
('itemListElement', ..., {
'title': ('name', {str}),
'description': ('description', {str}),
}), get_all=False)
return self.playlist_result(self._get_episodes_from_season(ss_id, url), ss_id, **metainfo)
class BilibiliCheeseBaseIE(BilibiliBaseIE):
def _extract_episode(self, season_info, ep_id):
episode_info = traverse_obj(season_info, (
'episodes', lambda _, v: v['id'] == int(ep_id)), get_all=False)
aid, cid = episode_info['aid'], episode_info['cid']
if traverse_obj(episode_info, 'ep_status') == -1:
raise ExtractorError('This course episode is not yet available.', expected=True)
if not traverse_obj(episode_info, 'playable'):
self.raise_login_required('You need to purchase the course to download this episode')
play_info = self._download_json(
'https://api.bilibili.com/pugv/player/web/playurl', ep_id,
query={'avid': aid, 'cid': cid, 'ep_id': ep_id, 'fnval': 16, 'fourk': 1},
headers=self._HEADERS, note='Downloading playinfo')['data']
return {
'id': str_or_none(ep_id),
'episode_id': str_or_none(ep_id),
'formats': self.extract_formats(play_info),
'extractor_key': BilibiliCheeseIE.ie_key(),
'extractor': BilibiliCheeseIE.IE_NAME,
'webpage_url': f'https://www.bilibili.com/cheese/play/ep{ep_id}',
**traverse_obj(episode_info, {
'episode': ('title', {str}),
'title': {lambda v: v and join_nonempty('index', 'title', delim=' - ', from_dict=v)},View on GitHub (pinned to 81ecd58b13)
Solutions
- Check the episode list on bilibili.com — episodes with a future unlock time are not fetchable; retry after the scheduled release.
- Restrict your download to published episodes (e.g. --playlist-items with the aired range).
- If the episode is visibly playable in a browser, update yt-dlp and report it (the ep_status semantics may have changed).
Defensive patterns
Strategy: validation
Validate before calling
# if you already have the season_info JSON (e.g. via API wrapper)
ep = next(e for e in season_info['episodes'] if e['id'] == int(ep_id))
if ep.get('ep_status') == -1:
schedule_retry_after_release(ep.get('publish_time'), ep_id) # skip for now Type guard
def cheese_episode_ready(ep) -> bool:
return isinstance(ep, dict) and ep.get('ep_status') != -1 and ep.get('playable') Try / catch
try:
info = ydl.extract_info(url, download=False)
except ExtractorError as e:
if 'not yet available' in str(e):
schedule_retry(url, after=release_date) # scheduled content; not an error
else:
raise Prevention
- Restrict --playlist-items to already-aired episodes
- Treat ep_status == -1 as 'scheduled', never retry immediately
- Watch the course page for unlock dates instead of polling
When it happens
Trigger: Downloading a full Cheese course playlist where later episodes are scheduled but not yet published; direct ep URLs for pre-announced episodes; episodes gated behind a course start date.
Common situations: Batch archiving a course on day one; users misreading 'coming soon' episode entries as available; timezone confusion about release times.
Related errors
- This video is not available yet. Release date: {start_date}
- This video may be deleted or geo-restricted. You might want
- This is a supporter-only video: {msg}
- {self.IE_NAME} said: {expired}
- {error}
AI-assisted analysis of yt-dlp/yt-dlp@81ecd58b13 (2026-08-22).
Data as JSON: /api/errors/f7539662ffca0a6c.
Report an issue: GitHub.