{"record":{"id":"e91257e31f5355ae","repo":"ytdl-org/youtube-dl","slug":"this-user-is-offline","errorCode":null,"errorMessage":"This user is offline.","messagePattern":"This user is offline\\.","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/bigo.py","lineNumber":45,"sourceCode":"        'only_matching': True,\n    }]\n\n    def _real_extract(self, url):\n        user_id = self._match_id(url)\n\n        info_raw = self._download_json(\n            'https://bigo.tv/studio/getInternalStudioInfo',\n            user_id, data=urlencode_postdata({'siteId': user_id}))\n\n        if not isinstance(info_raw, dict):\n            raise ExtractorError('Received invalid JSON data')\n        if info_raw.get('code'):\n            raise ExtractorError(\n                'Bigo says: %s (code %s)' % (info_raw.get('msg'), info_raw.get('code')), expected=True)\n        info = info_raw.get('data') or {}\n\n        if not info.get('alive'):\n            raise ExtractorError('This user is offline.', expected=True)\n\n        return {\n            'id': info.get('roomId') or user_id,\n            'title': info.get('roomTopic') or info.get('nick_name') or user_id,\n            'formats': [{\n                'url': info.get('hls_src'),\n                'ext': 'mp4',\n                'protocol': 'm3u8',\n            }],\n            'thumbnail': info.get('snapshot'),\n            'uploader': info.get('nick_name'),\n            'uploader_id': user_id,\n            'is_live': True,\n        }\n","sourceCodeStart":27,"sourceCodeEnd":60,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/bigo.py#L27-L60","documentation":"Raised by BigoIE._real_extract after a successful API response (no error code): the response's data.alive flag is falsy, meaning the channel exists but is not currently live-streaming. Since Bigo extraction targets live HLS streams (hls_src with m3u8 protocol), an offline user has nothing to extract, so it fails expected=True.","triggerScenarios":"Extracting any Bigo channel URL while the streamer is offline: API returns code 0 with data.alive = false/0/absent. Purely time-dependent — the same URL succeeds while the user is live.","commonSituations":"Monitoring scripts polling channel URLs between streams; users replaying links to streams that ended; time-zone mismatch about when a streamer goes live; channels that stream rarely.","solutions":["Retry while the channel is actually live — verify at https://bigo.tv/<user_id> that a LIVE badge/player shows.","For monitoring, poll the getInternalStudioInfo endpoint and only invoke full extraction when alive is truthy.","Handle this as an expected error and back off rather than re-triggering immediately.","Confirm the id belongs to the intended streamer; a wrong-but-existing id also reports offline."],"exampleFix":"// before - caller extracts directly\nfrom youtube_dl import YoutubeDL\nYoutubeDL().extract_info('https://bigo.tv/115976881', download=True)\n\n// after - probe liveness first via the same API the extractor uses, then extract only when live\nimport requests\nr = requests.post('https://bigo.tv/studio/getInternalStudioInfo', data={'siteId': '115976881'}).json()\nif r.get('code') or not (r.get('data') or {}).get('alive'):\n    print('channel offline or errored; retry later')\nelse:\n    YoutubeDL().extract_info('https://bigo.tv/115976881', download=True)","handlingStrategy":"validation","validationCode":"import requests\n\ndef bigo_user_is_live(user_id):\n    r = requests.post('https://bigo.tv/studio/getInternalStudioInfo', data={'siteId': user_id})\n    if r.status_code != 200:\n        return False\n    body = r.json()\n    return isinstance(body, dict) and not body.get('code') and bool((body.get('data') or {}).get('alive'))","typeGuard":"def is_live_bigo_data(info):\n    return isinstance(info, dict) and bool(info.get('alive')) and bool(info.get('hls_src'))","tryCatchPattern":"try:\n    ydl.extract_info(bigo_url)\nexcept ExtractorError as e:\n    if str(e) == 'This user is offline.':\n        schedule_next_poll(bigo_url)  # expected while streamer is off-air\n    else:\n        raise","preventionTips":["Poll the studio-info API for alive=true before invoking full extraction.","Space polls minutes apart; offline is the normal state between streams.","Confirm the numeric id against the channel page to avoid watching the wrong user."],"tags":["bigo","live-stream","offline","time-dependent","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}