{"record":{"id":"9ecdf7ab7999170d","repo":"ytdl-org/youtube-dl","slug":"unable-to-find-selected-tab","errorCode":null,"errorMessage":"Unable to find selected tab","messagePattern":"Unable to find selected tab","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/youtube.py","lineNumber":3996,"sourceCode":"                    continuation = self._extract_continuation(continuation_renderer)\n                    continue\n                renderer = continuation_item.get('richItemRenderer')\n                if renderer:\n                    for entry in self._rich_grid_entries(continuation_items):\n                        yield entry\n                    continuation = self._extract_continuation({'contents': continuation_items})\n                    continue\n\n            break\n\n    @staticmethod\n    def _extract_selected_tab(tabs):\n        for tab in tabs:\n            renderer = dict_get(tab, ('tabRenderer', 'expandableTabRenderer')) or {}\n            if renderer.get('selected') is True:\n                return renderer\n        else:\n            raise ExtractorError('Unable to find selected tab')\n\n    def _extract_uploader(self, metadata, data):\n        uploader = {}\n        renderers = traverse_obj(data,\n                                 ('sidebar', 'playlistSidebarRenderer', 'items'))\n        uploader['channel_id'] = self._extract_channel_id('', metadata=metadata, renderers=renderers)\n        uploader['uploader'] = (\n            self._extract_author_var('', 'name', renderers=renderers)\n            or self._extract_author_var('', 'name', metadata=metadata))\n        uploader['uploader_url'] = self._yt_urljoin(\n            self._extract_author_var('', 'url', metadata=metadata, renderers=renderers))\n        uploader['uploader_id'] = self._extract_uploader_id(uploader['uploader_url'])\n        uploader['channel'] = uploader['uploader']\n        return uploader\n\n    def _extract_and_report_alerts(self, data, expected=True, fatal=True, only_once=False):\n\n        def alerts():","sourceCodeStart":3978,"sourceCodeEnd":4014,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/youtube.py#L3978-L4014","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"def has_selected_tab(data: dict) -> bool:\n    tabs = traverse_obj(data, ('tabs',), default=[]) or []\n    return any(\n        (dict_get(tab, ('tabRenderer', 'expandableTabRenderer')) or {}).get('selected') is True\n        for tab in tabs)","typeGuard":"def find_selected_tab(tabs):\n    for tab in tabs or []:\n        renderer = dict_get(tab, ('tabRenderer', 'expandableTabRenderer')) or {}\n        if renderer.get('selected') is True:\n            return renderer\n    return None  # None instead of exception","tryCatchPattern":"try:\n    info = ydl.extract_info(channel_url)\nexcept ExtractorError as e:\n    if 'Unable to find selected tab' in str(e):\n        info = ydl.extract_info(channel_url + '/videos')  # force explicit tab\n    else:\n        raise","preventionTips":["Request tab-specific URLs (/videos, /playlists) so responses carry a selected tab.","Update the extractor promptly after YouTube browse-page redesigns."],"tags":["youtube","channel","tabs","site-change"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}