{"record":{"id":"1b6d9d559c914f96","repo":"ytdl-org/youtube-dl","slug":"unable-to-download-video-s","errorCode":null,"errorMessage":"Unable to download video %s","messagePattern":"Unable to download video (.+?)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/ivi.py","lineNumber":153,"sourceCode":"                message = error.get('message') or error.get('user_message')\n                extractor_msg = 'Unable to download video %s'\n                if origin == 'NotAllowedForLocation':\n                    self.raise_geo_restricted(message, self._GEO_COUNTRIES)\n                elif origin == 'NoRedisValidData':\n                    extractor_msg = 'Video %s does not exist'\n                elif site == 353:\n                    continue\n                elif bundled:\n                    raise ExtractorError(\n                        'This feature does not work from bundled exe. Run youtube-dl from sources.',\n                        expected=True)\n                elif not pycryptodomex_found:\n                    raise ExtractorError(\n                        'pycryptodomex not found. Please install it.',\n                        expected=True)\n                elif message:\n                    extractor_msg += ': ' + message\n                raise ExtractorError(extractor_msg % video_id, expected=True)\n            else:\n                break\n\n        result = video_json['result']\n        title = result['title']\n\n        quality = qualities(self._KNOWN_FORMATS)\n\n        formats = []\n        for f in result.get('files', []):\n            f_url = f.get('url')\n            content_format = f.get('content_format')\n            if not f_url or '-MDRM-' in content_format or '-FPS-' in content_format:\n                continue\n            formats.append({\n                'url': f_url,\n                'format_id': content_format,\n                'quality': quality(content_format),","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/ivi.py#L135-L171","documentation":"The ivi.ru extractor's generic per-video failure: the light API answered with an error object whose origin was not the geo or not-exist cases and no dependency/bundling issue applied, so the default 'Unable to download video %s' (optionally suffixed with the server's message) is raised as an expected ExtractorError.","triggerScenarios":"POST to ivi's _LIGHT_URL (contentdelegation) returning {'error': {...}} with an unknown origin - e.g. 'CROSS_DEVICE_LIMIT', paid-content errors, or malformed/expired content IDs that still resolve to a generic error.","commonSituations":"Paid ivi.ru content without a subscription, content removed between listing and playback, or server-side API changes altering the error envelope.","solutions":["Read the appended server message (if any) - it identifies the actual rejection reason.","Confirm the video plays for free in a browser from your region.","Update youtube-dl/yt-dlp for current ivi API error semantics."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(ivi_url)\nexcept ExtractorError as e:\n    if str(e).startswith('Unable to download video'):\n        # check for paid-content/geo hints in the tail of the message, else retry once\n        handle_ivi_rejection(str(e))","preventionTips":["Capture the server message suffix to classify paid vs transient failures.","Confirm free-tier availability of ivi content before batch jobs.","Keep extractor current; ivi error origins evolve."],"tags":["api","extractor","ivi","error-code","streaming"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}