{"record":{"id":"ebd47824a695e45e","repo":"ytdl-org/youtube-dl","slug":"s-said-s-ebd478","errorCode":null,"errorMessage":"%s said: %s","messagePattern":"%s said: %s","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/bilibili.py","lineNumber":117,"sourceCode":"                'timestamp': 1488382634,\n                'upload_date': '20170301',\n            },\n            'params': {\n                'skip_download': True,  # Test metadata only\n            },\n        }]\n    }, {\n        # new BV video id format\n        'url': 'https://www.bilibili.com/video/BV1JE411F741',\n        'only_matching': True,\n    }]\n\n    _APP_KEY = 'iVGUTjsxvpLeuDCf'\n    _BILIBILI_KEY = 'aHRmhWMLkdeMuILqORnYZocwMBpMEOdt'\n\n    def _report_error(self, result):\n        if 'message' in result:\n            raise ExtractorError('%s said: %s' % (self.IE_NAME, result['message']), expected=True)\n        elif 'code' in result:\n            raise ExtractorError('%s returns error %d' % (self.IE_NAME, result['code']), expected=True)\n        else:\n            raise ExtractorError('Can\\'t extract Bangumi episode ID')\n\n    def _real_extract(self, url):\n        url, smuggled_data = unsmuggle_url(url, {})\n\n        mobj = re.match(self._VALID_URL, url)\n        video_id = mobj.group('id') or mobj.group('id_bv')\n        anime_id = mobj.group('anime_id')\n        webpage = self._download_webpage(url, video_id)\n\n        if 'anime/' not in url:\n            cid = self._search_regex(\n                r'\\bcid(?:[\"\\']:|=)(\\d+)', webpage, 'cid',\n                default=None\n            ) or compat_parse_qs(self._search_regex(","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/bilibili.py#L99-L135","documentation":"Raised by BiliBiliBangumiIE._report_error when a Bangumi API call returns a result dict containing a 'message' key: the error interpolates the extractor name ('Bilibili Bangumi') and the API's own message text (e.g. 'Bilibili Bangumi said: Sorry, the video is only available in mainland China'). Expected=True — a server-side rejection carried through verbatim.","triggerScenarios":"Calling the Bangumi playurl/season API (signed with _APP_KEY/_BILIBILI_KEY) for content the API refuses: region-locked videos for non-mainland-China IPs, removed episodes, or parameter errors — any response whose JSON includes a non-empty 'message' field hits this branch before the code branch.","commonSituations":"Non-CN IPs extracting region-locked bangumi (the dominant case); episodes pulled for licensing reasons; stale APP_KEY/signing secret after Bilibili rotated it, causing auth-reject messages; wrong anime/episode ids producing API error messages.","solutions":["Read the interpolated message — it is Bilibili's own reason; 'mainland China' messages require a CN IP (VPN) or a different source.","For removed episodes, check the bangumi page in a browser for replacement ids.","If all requests fail with auth-style messages, the bundled _APP_KEY/_BILIBILI_KEY may be stale — update them from the current web app and report upstream.","Handle as expected in batch tools: log and skip rather than abort the run."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(bangumi_url)\nexcept ExtractorError as e:\n    msg = str(e)\n    if 'said:' in msg:\n        if 'mainland China' in msg:\n            raise RegionBlocked(msg) from e\n        log_api_rejection(bangumi_url, msg)  # server-side reason; not retryable as-is\n    else:\n        raise","preventionTips":["Route bangumi requests through a mainland-China IP for region-locked content.","Batch tools should log 'said:' rejections and continue, not abort.","Keep extractor versions current — Bilibili rotates keys and envelopes over time."],"tags":["bilibili","bangumi","api-error","geo-restriction","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}