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

  1. Update youtube-dl (or yt-dlp) — tab handling is patched whenever the browse layout changes.
  2. Try the specific tab URL form (e.g. /videos, /playlists) instead of the bare channel URL so the response includes an explicit tab.
  3. If developing, dump data['tabs'] and check which renderer key now marks selection; extend dict_get and the selected check.
  4. 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

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


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