{"record":{"id":"5c6fda46a1d8381e","repo":"ytdl-org/youtube-dl","slug":"s-said-s-5c6fda","errorCode":null,"errorMessage":"%s said: %s","messagePattern":"%s said: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/rutv.py","lineNumber":147,"sourceCode":"        video_path = mobj.group('path')\n\n        if re.match(r'flash\\d+v', video_path):\n            video_type = 'video'\n        elif video_path.startswith('iframe'):\n            video_type = mobj.group('type')\n            if video_type == 'swf':\n                video_type = 'video'\n        elif video_path.startswith('index/iframe/cast_id'):\n            video_type = 'live'\n\n        is_live = video_type == 'live'\n\n        json_data = self._download_json(\n            'http://player.rutv.ru/iframe/data%s/id/%s' % ('live' if is_live else 'video', video_id),\n            video_id, 'Downloading JSON')\n\n        if json_data['errors']:\n            raise ExtractorError('%s said: %s' % (self.IE_NAME, json_data['errors']), expected=True)\n\n        playlist = json_data['data']['playlist']\n        medialist = playlist['medialist']\n        media = medialist[0]\n\n        if media['errors']:\n            raise ExtractorError('%s said: %s' % (self.IE_NAME, media['errors']), expected=True)\n\n        view_count = playlist.get('count_views')\n        priority_transport = playlist['priority_transport']\n\n        thumbnail = media['picture']\n        width = int_or_none(media['width'])\n        height = int_or_none(media['height'])\n        description = media['anons']\n        title = media['title']\n        duration = int_or_none(media.get('duration'))\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/rutv.py#L129-L165","documentation":"Raised by the RUTV (Russian TV) extractor when the player JSON from player.rutv.ru/iframe/data.../id/<id> has a non-empty top-level 'errors' list. Message: 'RUTV said: <errors payload>'. Expected=True. This is the first of two error checks - the outer API call itself failed before any playlist data is read.","triggerScenarios":"Extracting a rutv.ru (or rtr-vesti.ru) video/live id for which the iframe data endpoint returns errors: invalid id, expired live stream, geo-blocked content.","commonSituations":"Following old rutv.ru links after the service was reorganized into smotrim.ru; catching a live stream outside its broadcast window; regional restrictions.","solutions":["Read the interpolated errors payload - it names the exact server-side reason.","Verify the id against the current site; RUTV content largely moved to vgtrk/smotrim players - find the new URL.","Drop dead ids from playlists.","If content plays in a browser, the endpoint/JSON shape changed - update youtube-dl."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url)\nexcept ExtractorError as e:\n    if str(e).startswith('RUTV said:'):\n        log(e)  # outer API errors: invalid id / geo / ended stream\n    else:\n        raise","preventionTips":["Read the interpolated errors payload for the true cause.","Note rutv.ru is a legacy service - prefer current vgtrk/smotrim URLs when they exist.","Do not retry ids that return errors on the outer endpoint."],"tags":["rutv","site-error","legacy-service","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}