ytdl-org/youtube-dl · error · ExtractorError

Received invalid JSON data

Error message

Received invalid JSON data

What it means

Raised by BigoIE._real_extract when the POST to https://bigo.tv/studio/getInternalStudioInfo (with siteId=<user_id>) succeeds at the HTTP level but the parsed JSON body is not an object — e.g. a JSON string, number, array, or null. _download_json only guarantees valid JSON, not a dict shape, so the extractor guards the type before accessing keys and fails hard (not expected=True) because a non-dict response means an API contract break.

Source

Thrown at youtube_dl/extractor/bigo.py:38

        },
        'skip': 'livestream',
    }, {
        'url': 'https://www.bigo.tv/th/Tarlerm1304',
        'only_matching': True,
    }, {
        'url': 'https://bigo.tv/115976881',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        user_id = self._match_id(url)

        info_raw = self._download_json(
            'https://bigo.tv/studio/getInternalStudioInfo',
            user_id, data=urlencode_postdata({'siteId': user_id}))

        if not isinstance(info_raw, dict):
            raise ExtractorError('Received invalid JSON data')
        if info_raw.get('code'):
            raise ExtractorError(
                'Bigo says: %s (code %s)' % (info_raw.get('msg'), info_raw.get('code')), expected=True)
        info = info_raw.get('data') or {}

        if not info.get('alive'):
            raise ExtractorError('This user is offline.', expected=True)

        return {
            'id': info.get('roomId') or user_id,
            'title': info.get('roomTopic') or info.get('nick_name') or user_id,
            'formats': [{
                'url': info.get('hls_src'),
                'ext': 'mp4',
                'protocol': 'm3u8',
            }],
            'thumbnail': info.get('snapshot'),
            'uploader': info.get('nick_name'),

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Reproduce the POST manually (curl -d 'siteId=<id>') and inspect the raw body to see what shape Bigo now returns.
  2. If the shape moved (e.g. data now nested or returned as a JSON string), update the isinstance check and field access in bigo.py:38.
  3. Confirm the user_id captured from the URL is a valid numeric Bigo id.
  4. If the endpoint was replaced, locate the new studio-info endpoint in the site's JS and retarget _download_json.

Example fix

// before
info_raw = self._download_json('https://bigo.tv/studio/getInternalStudioInfo', user_id, data=urlencode_postdata({'siteId': user_id}))
if not isinstance(info_raw, dict):
    raise ExtractorError('Received invalid JSON data')

// after: include the actual type/body to speed diagnosis
if not isinstance(info_raw, dict):
    raise ExtractorError('Bigo returned unexpected JSON (type: %s): %.200r' % (type(info_raw).__name__, info_raw))
Defensive patterns

Strategy: type-guard

Validate before calling

import requests

def bigo_api_returns_dict(user_id):
    r = requests.post('https://bigo.tv/studio/getInternalStudioInfo', data={'siteId': user_id})
    try:
        body = r.json()
    except ValueError:
        return False
    return isinstance(body, dict)

Type guard

def is_bigo_dict_response(body):
    return isinstance(body, dict)

Try / catch

try:
    ydl.extract_info('https://bigo.tv/%s' % user_id)
except ExtractorError as e:
    if str(e) == 'Received invalid JSON data':
        # API contract break; not transient - inspect the endpoint manually
        raise ApiSchemaChanged('bigo getInternalStudioInfo no longer returns a dict') from e
    raise

Prevention

When it happens

Trigger: The getInternalStudioInfo endpoint returning a scalar/array JSON body: API version changes, WAF/CDN interference returning a JSON-encoded string like "ok", or an A/B backend. Any user_id where the response decodes to a non-dict triggers it before any field checks run.

Common situations: Bigo changing its internal studio API response envelope; anti-bot layers returning terse JSON strings; requesting with malformed siteId that elicits a non-object error body; extractor drift after site updates.

Understand the failure class

Related errors


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