ytdl-org/youtube-dl · error · ExtractorError

Can't extract Bangumi episode ID

Error message

Can't extract Bangumi episode ID

What it means

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.

Source

Thrown at youtube_dl/extractor/bilibili.py:121

                'skip_download': True,  # Test metadata only
            },
        }]
    }, {
        # new BV video id format
        'url': 'https://www.bilibili.com/video/BV1JE411F741',
        'only_matching': True,
    }]

    _APP_KEY = 'iVGUTjsxvpLeuDCf'
    _BILIBILI_KEY = 'aHRmhWMLkdeMuILqORnYZocwMBpMEOdt'

    def _report_error(self, result):
        if 'message' in result:
            raise ExtractorError('%s said: %s' % (self.IE_NAME, result['message']), expected=True)
        elif 'code' in result:
            raise ExtractorError('%s returns error %d' % (self.IE_NAME, result['code']), expected=True)
        else:
            raise ExtractorError('Can\'t extract Bangumi episode ID')

    def _real_extract(self, url):
        url, smuggled_data = unsmuggle_url(url, {})

        mobj = re.match(self._VALID_URL, url)
        video_id = mobj.group('id') or mobj.group('id_bv')
        anime_id = mobj.group('anime_id')
        webpage = self._download_webpage(url, video_id)

        if 'anime/' not in url:
            cid = self._search_regex(
                r'\bcid(?:["\']:|=)(\d+)', webpage, 'cid',
                default=None
            ) or compat_parse_qs(self._search_regex(
                [r'EmbedPlayer\([^)]+,\s*"([^"]+)"\)',
                 r'EmbedPlayer\([^)]+,\s*\\"([^"]+)\\"\)',
                 r'<iframe[^>]+src="https://secure\.bilibili\.com/secure,([^"]+)"'],
                webpage, 'player parameters'))['cid'][0]

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Dump the raw API response (add a temporary log before _report_error) to see the actual shape.
  2. If the envelope changed, update the field access feeding _report_error and the episode-id extraction (bilibili.py:121).
  3. Confirm the signed request (APP_KEY/secret) is still valid — auth failures sometimes return bodies without message/code.
  4. Update youtube-dl / yt-dlp: newer versions track Bilibili API changes and this extractor was heavily reworked there.

Example fix

// before
else:
    raise ExtractorError('Can\'t extract Bangumi episode ID')

// after: include a sample of the payload so the schema mismatch is diagnosable
else:
    raise ExtractorError('Can\'t extract Bangumi episode ID (unexpected API result: %.200r)' % (result,))
Defensive patterns

Strategy: try-catch

Try / catch

try:
    ydl.extract_info(bangumi_url)
except ExtractorError as e:
    if "Can't extract Bangumi episode ID" in str(e):
        # schema drift, not a server rejection; update extractor, don't retry
        raise ExtractorOutdated('bilibili bangumi API envelope changed') from e
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/cd1d481aca770db1. Report an issue: GitHub.