{"record":{"id":"4dc6edc6ec977f21","repo":"ytdl-org/youtube-dl","slug":"s-said-s-4dc6ed","errorCode":null,"errorMessage":"%s said: %s","messagePattern":"%s said: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/mojvideo.py","lineNumber":40,"sourceCode":"            'title': 'V avtu pred mano rdečelaska - Alfi Nipič',\n            'thumbnail': r're:^http://.*\\.jpg$',\n            'duration': 242,\n        }\n    }\n\n    def _real_extract(self, url):\n        mobj = re.match(self._VALID_URL, url)\n        video_id = mobj.group('id')\n        display_id = mobj.group('display_id')\n\n        # XML is malformed\n        playerapi = self._download_webpage(\n            'http://www.mojvideo.com/playerapi.php?v=%s&t=1' % video_id, display_id)\n\n        if '<error>true</error>' in playerapi:\n            error_desc = self._html_search_regex(\n                r'<errordesc>([^<]*)</errordesc>', playerapi, 'error description', fatal=False)\n            raise ExtractorError('%s said: %s' % (self.IE_NAME, error_desc), expected=True)\n\n        title = self._html_search_regex(\n            r'<title>([^<]+)</title>', playerapi, 'title')\n        video_url = self._html_search_regex(\n            r'<file>([^<]+)</file>', playerapi, 'video URL')\n        thumbnail = self._html_search_regex(\n            r'<preview>([^<]+)</preview>', playerapi, 'thumbnail', fatal=False)\n        duration = parse_duration(self._html_search_regex(\n            r'<duration>([^<]+)</duration>', playerapi, 'duration', fatal=False))\n\n        return {\n            'id': video_id,\n            'display_id': display_id,\n            'url': video_url,\n            'title': title,\n            'thumbnail': thumbnail,\n            'duration': duration,\n        }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/mojvideo.py#L22-L58","documentation":"Raised by the mojvideo.com extractor when the playerapi.php XML response contains '<error>true</error>'. The extractor then scrapes <errordesc> for the human-readable reason and re-raises it prefixed with the extractor name. Expected=True — a faithful relay of the site's own error channel.","triggerScenarios":"GET http://www.mojvideo.com/playerapi.php?v={id}&t=1 returns malformed XML containing <error>true</error>; <errordesc> is searched with fatal=False, so a missing errordesc yields None and the message reads 'mojvideo said: None'.","commonSituations":"Video deleted from mojvideo; private/pending-approval videos; the Slovenian service (largely defunct) returning errors for all ids; API changes renaming errordesc.","solutions":["Read the errordesc text — it is mojvideo's stated reason.","Verify the video at www.mojvideo.com in a browser.","If the whole service is offline/erroring, source the media elsewhere; no client fix recovers it."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def mojvideo_api_error(api_xml):\n    return isinstance(api_xml, str) and '<error>true</error>' in api_xml","tryCatchPattern":"try:\n    info = ydl.extract_info(url, download=False)\nexcept ExtractorError as e:\n    if 'mojvideo said:' in str(e):\n        mark_permanently_dead(url)  # site's API declared the video gone\n    else:\n        raise","preventionTips":["Verify mojvideo ids in a browser before queueing (service is largely defunct).","Treat '<error>true</error>' responses as permanent; do not retry."],"tags":["xml-api","service-error","expected-error"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}