{"record":{"id":"19837cfe1878f6d6","repo":"ytdl-org/youtube-dl","slug":"error-19837c","errorCode":null,"errorMessage":"error","messagePattern":"error","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/xhamster.py","lineNumber":143,"sourceCode":"        'only_matching': True,\n    }, {\n        'url': 'https://xhvid.com/videos/lk-mm-xhc6wn6',\n        'only_matching': True,\n    }]\n\n    def _real_extract(self, url):\n        mobj = re.match(self._VALID_URL, url)\n        video_id = mobj.group('id') or mobj.group('id_2')\n        display_id = mobj.group('display_id') or mobj.group('display_id_2')\n\n        desktop_url = re.sub(r'^(https?://(?:.+?\\.)?)m\\.', r'\\1', url)\n        webpage, urlh = self._download_webpage_handle(desktop_url, video_id)\n\n        error = self._html_search_regex(\n            r'<div[^>]+id=[\"\\']videoClosed[\"\\'][^>]*>(.+?)</div>',\n            webpage, 'error', default=None)\n        if error:\n            raise ExtractorError(error, expected=True)\n\n        age_limit = self._rta_search(webpage)\n\n        def get_height(s):\n            return int_or_none(self._search_regex(\n                r'^(\\d+)[pP]', s, 'height', default=None))\n\n        initials = self._parse_json(\n            self._search_regex(\n                (r'window\\.initials\\s*=\\s*({.+?})\\s*;\\s*</script>',\n                 r'window\\.initials\\s*=\\s*({.+?})\\s*;'), webpage, 'initials',\n                default='{}'),\n            video_id, fatal=False)\n        if initials:\n            video = initials['videoModel']\n            title = video['title']\n            formats = []\n            format_urls = set()","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/xhamster.py#L125-L161","documentation":"Raised by the xHamster extractor when the desktop page contains a <div id=\"videoClosed\"> element. xHamster uses this element to state why a video is unavailable (removed, private, banned in region, disabled by uploader), and its text is forwarded as the error message.","triggerScenarios":"Downloading an xHamster video whose page (after rewriting mobile URLs to desktop) matches r'<div[^>]+id=[\"\\']videoClosed[\"\\'][^>]*>(.+?)</div>' with non-empty content.","commonSituations":"Videos set to private or deleted by the uploader; content banned in the requester's country (some regions redirect to a closed notice); uploader accounts terminated.","solutions":["Read the videoClosed div text forwarded in the error — it names the exact cause.","For region bans, access via an permitted region or accept unavailability.","For private/deleted videos, no download is possible without the uploader's grant."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    info = ydl.extract_info(url)\nexcept ExtractorError as e:\n    if 'videoClosed' in str(e) or is_site_availability_error(e):\n        classify_and_skip(url, str(e))\n    else:\n        raise","preventionTips":["Check the videoClosed message text — it distinguishes private, deleted, and region-banned.","Use permitted-region egress for region-banned content.","Do not retry; availability errors are deterministic per video."],"tags":["site-error","video-unavailable","extractor","xhamster"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}