{"record":{"id":"cd1d481aca770db1","repo":"ytdl-org/youtube-dl","slug":"can-t-extract-bangumi-episode-id","errorCode":null,"errorMessage":"Can't extract Bangumi episode ID","messagePattern":"Can't extract Bangumi episode ID","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/bilibili.py","lineNumber":121,"sourceCode":"                '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(\n                [r'EmbedPlayer\\([^)]+,\\s*\"([^\"]+)\"\\)',\n                 r'EmbedPlayer\\([^)]+,\\s*\\\\\"([^\"]+)\\\\\"\\)',\n                 r'<iframe[^>]+src=\"https://secure\\.bilibili\\.com/secure,([^\"]+)\"'],\n                webpage, 'player parameters'))['cid'][0]","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/bilibili.py#L103-L139","documentation":"Final branch of BiliBiliBangumiIE._report_error: the API result dict contains neither 'message' nor 'code', so the extractor cannot extract a Bangumi episode ID from it and raises this bare extraction failure (not expected=True — it signals a parsing/schema problem rather than a clean server rejection). It means the API responded with an object whose shape the extractor does not understand.","triggerScenarios":"A Bangumi API response whose JSON is a dict lacking both keys — e.g. a successful-but-empty object, a redesigned response envelope, or the wrong endpoint being parsed into _report_error. Distinguish from 53/54: those carry server reasons; this one means the extractor found nothing it recognizes at all.","commonSituations":"Bilibili migrated the bangumi API to a new envelope (data nested under 'result' etc.) after this extractor version; middleware/CDN returning an empty {}; debugging with a patched URL that hits a different endpoint; result accidentally an error page parsed as JSON.","solutions":["Dump the raw API response (add a temporary log before _report_error) to see the actual shape.","If the envelope changed, update the field access feeding _report_error and the episode-id extraction (bilibili.py:121).","Confirm the signed request (APP_KEY/secret) is still valid — auth failures sometimes return bodies without message/code.","Update youtube-dl / yt-dlp: newer versions track Bilibili API changes and this extractor was heavily reworked there."],"exampleFix":"// before\nelse:\n    raise ExtractorError('Can\\'t extract Bangumi episode ID')\n\n// after: include a sample of the payload so the schema mismatch is diagnosable\nelse:\n    raise ExtractorError('Can\\'t extract Bangumi episode ID (unexpected API result: %.200r)' % (result,))","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(bangumi_url)\nexcept ExtractorError as e:\n    if \"Can't extract Bangumi episode ID\" in str(e):\n        # schema drift, not a server rejection; update extractor, don't retry\n        raise ExtractorOutdated('bilibili bangumi API envelope changed') from e\n    raise","preventionTips":["Update to the latest extractor build when this appears — it almost always means API drift.","Pin and track extractor versions so envelope changes are caught in CI, not production.","Capture the raw API response when triaging; the bare message hides the payload."],"tags":["bilibili","bangumi","schema-change","extraction-failure","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}