{"record":{"id":"717b17857c56a227","repo":"ytdl-org/youtube-dl","slug":"s-said-s-717b17","errorCode":null,"errorMessage":"%s said: %s","messagePattern":"%s said: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/srgssr.py","lineNumber":79,"sourceCode":"    def _get_media_data(self, bu, media_type, media_id):\n        query = {'onlyChapters': True} if media_type == 'video' else {}\n        full_media_data = self._download_json(\n            'https://il.srgssr.ch/integrationlayer/2.0/%s/mediaComposition/%s/%s.json'\n            % (bu, media_type, media_id),\n            media_id, query=query)['chapterList']\n        try:\n            media_data = next(\n                x for x in full_media_data if x.get('id') == media_id)\n        except StopIteration:\n            raise ExtractorError('No media information found')\n\n        block_reason = media_data.get('blockReason')\n        if block_reason and block_reason in self._ERRORS:\n            message = self._ERRORS[block_reason]\n            if block_reason == 'GEOBLOCK':\n                self.raise_geo_restricted(\n                    msg=message, countries=self._GEO_COUNTRIES)\n            raise ExtractorError(\n                '%s said: %s' % (self.IE_NAME, message), expected=True)\n\n        return media_data\n\n    def _real_extract(self, url):\n        bu, media_type, media_id = re.match(self._VALID_URL, url).groups()\n        media_data = self._get_media_data(bu, media_type, media_id)\n        title = media_data['title']\n\n        formats = []\n        q = qualities(['SD', 'HD'])\n        for source in (media_data.get('resourceList') or []):\n            format_url = source.get('url')\n            if not format_url:\n                continue\n            protocol = source.get('protocol')\n            quality = source.get('quality')\n            format_id = []","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/srgssr.py#L61-L97","documentation":"SRGSSRIE._get_media_data reads the resolved chapter's 'blockReason' and maps it through the extractor's _ERRORS table. GEOBLOCK routes to raise_geo_restricted with the allowed countries; any other known reason is raised as '<SRF/RTS/...> said: <mapped message>' with expected=True. It is the platform's explicit content-blocking signal (end of availability, age rating, legal restrictions).","triggerScenarios":"A mediaComposition chapter carrying blockReason equal to one of the extractor's known keys (e.g. 'ENDEAVOUR_END_AVAILABILITY' style 'end of availability' codes, geoblock, legal block). The chapter exists (so the StopIteration path passed) but the platform refuses playback.","commonSituations":"Swiss content expiring after its broadcast window (SRF/RTS take downs after a fixed availability period); viewers outside Switzerland/Liechtenstein hitting GEOBLOCK; sports content with shorter licenses than regular shows.","solutions":["Read the mapped message - 'end of availability' means the content expired permanently and cannot be fetched.","If GEOBLOCK, use a CH/LI VPN or proxy; the allowed countries list is embedded in the extractor.","Look for the same program on the broadcaster's official YouTube channel after the window.","Update yt-dlp if blockReason keys were added/renamed upstream."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"chapter = get_media_data(bu, media_type, media_id)\nif chapter.get('blockReason'):\n    reason = chapter['blockReason']\n    if reason == 'GEOBLOCK':\n        use_ch_proxy()\n    else:\n        skip(media_id, reason='blocked: ' + reason)","typeGuard":"def chapter_is_blocked(chapter: dict) -> bool:\n    return bool(chapter.get('blockReason'))","tryCatchPattern":"try:\n    extract(url)\nexcept GeoRestrictedError:\n    retry_via_ch_proxy()\nexcept ExtractorError as e:\n    if e.expected and 'said:' in str(e):\n        drop_expired(media_id, str(e))\n    else:\n        raise","preventionTips":["Check blockReason yourself before queuing SRGSSR downloads.","Use CH/LI egress for geoblocked Swiss content.","Download broadcast content within its availability window; expiry is permanent."],"tags":["srgssr","geo-restricted","expired-content","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}