{"record":{"id":"a2e38360a9cbd7c5","repo":"ytdl-org/youtube-dl","slug":"no-stream-data-url","errorCode":null,"errorMessage":"No stream data/URL","messagePattern":"No stream data/URL","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/gbnews.py","lineNumber":114,"sourceCode":"        uvid = video_data['data-uvid']\n        dtype = video_data.get('data-type')\n        stream_data = self._download_json(\n            '%s/api/%s/stream/%s' % (meta_url, 'show' if dtype == 'vod' else dtype, uvid),\n            uvid,\n            query={\n                'key': video_data.get('data-key'),\n                'platform': self._PLATFORM,\n            },\n            headers={\n                'Token': video_data.get('data-token'),\n                'Token-Expiry': video_data.get('data-expiry'),\n                'Uvid': uvid,\n            }, fatal=False)\n\n        stream_url = traverse_obj(stream_data, (\n            'response', 'stream', T(url_or_none)))\n        if not stream_url:\n            raise ExtractorError('No stream data/URL')\n\n        # now known to be a dict\n        stream_data = stream_data['response']\n        drm = stream_data.get('drm')\n        if drm:\n            self.report_drm(uvid)\n\n        formats = self._extract_m3u8_formats(\n            stream_url, uvid, ext='mp4', entry_protocol='m3u8_native',\n            fatal=False)\n        # exception if no formats\n        self._sort_formats(formats)\n\n        return {\n            'id': uvid,\n            'display_id': display_id,\n            'title': (traverse_obj(stream_data, ('title', T(txt_or_none)))\n                      or self._og_search_title(webpage, default=None)","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/gbnews.py#L96-L132","documentation":"Raised by the GB News extractor after fetching <api_hostname>/api/<type>/stream/<uvid> when response.stream is missing or not a valid URL (traverse_obj with url_or_none filter). The stream request uses fatal=False, so HTTP failures also arrive here with stream_data set to None.","triggerScenarios":"The stream API rejects the Token/Token-Expiry/Uvid headers (expired token from the page), returns DRM-only or geo-blocked content with no stream URL, or the request failed silently due to fatal=False.","commonSituations":"Stale page HTML with expired tokens (page cached long before extraction), geo-restriction to the UK, DRM-protected streams, or an API response-shape change by Simplestream.","solutions":["Re-download the page fresh (clear cache) so data-token/data-expiry are current and retry","Run with -v to confirm the stream API request/response behind the swallowed failure","Check geo/VPN: GB News streams are typically UK-only","Update youtube-dl/yt-dlp; if still failing, extract the stream URL manually from devtools"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import requests\nr = requests.get(f'{api_hostname}/api/{dtype}/stream/{uvid}', headers=hdrs, params={'platform': 'gbnews'})\nstream = r.json().get('response', {}).get('stream')\nif not isinstance(stream, str) or not stream.startswith('http'):\n    print('Stream endpoint returned no playable URL (token/geo/DRM?)')","typeGuard":"from youtube_dl.utils import url_or_none\ndef stream_url_ok(stream_data):\n    return url_or_none(stream_data and stream_data.get('response', {}).get('stream')) is not None","tryCatchPattern":"try:\n    info = ydl.extract_info(url)\nexcept DownloadError as e:\n    if 'No stream data/URL' in str(e):\n        refetch_page_and_retry(url)  # tokens in the page may be stale\n    else:\n        raise","preventionTips":["Always fetch the page fresh immediately before extraction so data-token/data-expiry are current","Use a UK exit for GB News streams","Accept that DRM-flagged responses cannot be downloaded"],"tags":["gbnews","streaming","token-expiry","geo-restriction"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}