ytdl-org/youtube-dl · error · ExtractorError
Unable to find selected tab
Error message
Unable to find selected tab
What it means
Raised by the static _extract_selected_tab used by YouTube tab/playlist extractors: given the tabs list from a channel/playlist page's response, no tab renderer had selected=True (checked across tabRenderer and expandableTabRenderer). The selected tab carries the content being extracted, so its absence aborts with this internal error.
Source
Thrown at youtube_dl/extractor/youtube.py:3996
continuation = self._extract_continuation(continuation_renderer)
continue
renderer = continuation_item.get('richItemRenderer')
if renderer:
for entry in self._rich_grid_entries(continuation_items):
yield entry
continuation = self._extract_continuation({'contents': continuation_items})
continue
break
@staticmethod
def _extract_selected_tab(tabs):
for tab in tabs:
renderer = dict_get(tab, ('tabRenderer', 'expandableTabRenderer')) or {}
if renderer.get('selected') is True:
return renderer
else:
raise ExtractorError('Unable to find selected tab')
def _extract_uploader(self, metadata, data):
uploader = {}
renderers = traverse_obj(data,
('sidebar', 'playlistSidebarRenderer', 'items'))
uploader['channel_id'] = self._extract_channel_id('', metadata=metadata, renderers=renderers)
uploader['uploader'] = (
self._extract_author_var('', 'name', renderers=renderers)
or self._extract_author_var('', 'name', metadata=metadata))
uploader['uploader_url'] = self._yt_urljoin(
self._extract_author_var('', 'url', metadata=metadata, renderers=renderers))
uploader['uploader_id'] = self._extract_uploader_id(uploader['uploader_url'])
uploader['channel'] = uploader['uploader']
return uploader
def _extract_and_report_alerts(self, data, expected=True, fatal=True, only_once=False):
def alerts():View on GitHub (pinned to 956b8c5855)
Solutions
- Update youtube-dl (or yt-dlp) — tab handling is patched whenever the browse layout changes.
- Try the specific tab URL form (e.g. /videos, /playlists) instead of the bare channel URL so the response includes an explicit tab.
- If developing, dump data['tabs'] and check which renderer key now marks selection; extend dict_get and the selected check.
- Verify the channel/playlist actually exists — nonexistent ones can return tab-less alert payloads.
Defensive patterns
Strategy: type-guard
Validate before calling
def has_selected_tab(data: dict) -> bool:
tabs = traverse_obj(data, ('tabs',), default=[]) or []
return any(
(dict_get(tab, ('tabRenderer', 'expandableTabRenderer')) or {}).get('selected') is True
for tab in tabs) Type guard
def find_selected_tab(tabs):
for tab in tabs or []:
renderer = dict_get(tab, ('tabRenderer', 'expandableTabRenderer')) or {}
if renderer.get('selected') is True:
return renderer
return None # None instead of exception Try / catch
try:
info = ydl.extract_info(channel_url)
except ExtractorError as e:
if 'Unable to find selected tab' in str(e):
info = ydl.extract_info(channel_url + '/videos') # force explicit tab
else:
raise Prevention
- Request tab-specific URLs (/videos, /playlists) so responses carry a selected tab.
- Update the extractor promptly after YouTube browse-page redesigns.
When it happens
Trigger: Extracting a channel/playlist URL where the initial data's tabs array is empty, all unselected, or uses a new renderer type not in ('tabRenderer', 'expandableTabRenderer') — often after YouTube changes its browse-response structure, or when a continuation-only payload is passed.
Common situations: YouTube browse-page schema changes; channel URLs whose response degenerates to an error/alert page (alerts were not yet the failure path); outdated youtube-dl against a redesigned channel page.
Related errors
- Cannot identify player %r
- Unable to extract nsig function code
- Unable to recognize tab page
- An extractor error has occurred.
- Unable to log in
AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14).
Data as JSON: /api/errors/9ecdf7ab7999170d.
Report an issue: GitHub.