{"record":{"id":"7009dd973398d209","repo":"ytdl-org/youtube-dl","slug":"s-is-offline-7009dd","errorCode":null,"errorMessage":"%s is offline","messagePattern":"(.+?) is offline","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/trovo.py","lineNumber":56,"sourceCode":"    programInfo\t{\n      coverUrl\n      id\n      streamInfo {\n        desc\n        playUrl\n      }\n      title\n    }\n    streamerInfo {\n        nickName\n        uid\n        userName\n    }\n  }\n}''' % username,\n            })['data']['getLiveInfo']\n        if live_info.get('isLive') == 0:\n            raise ExtractorError('%s is offline' % username, expected=True)\n        program_info = live_info['programInfo']\n        program_id = program_info['id']\n        title = self._live_title(program_info['title'])\n\n        formats = []\n        for stream_info in (program_info.get('streamInfo') or []):\n            play_url = stream_info.get('playUrl')\n            if not play_url:\n                continue\n            format_id = stream_info.get('desc')\n            formats.append({\n                'format_id': format_id,\n                'height': int_or_none(format_id[:-1]) if format_id else None,\n                'url': play_url,\n            })\n        self._sort_formats(formats)\n\n        info = {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/trovo.py#L38-L74","documentation":"Raised by TrovoIE when the GraphQL getLiveInfo response reports isLive == 0 for the requested channel: the streamer exists but is not currently broadcasting. Expected=True, so it reads as a normal 'channel offline' condition.","triggerScenarios":"Running the extractor on https://trovo.live/s/<username> (or clip-less channel URL) while the channel is offline; the API succeeds and returns programInfo-less liveInfo with isLive:0.","commonSituations":"Monitoring scripts polling live channels; following schedule links after a stream ended; VOD/clip URLs mis-pasted as live channel URLs.","solutions":["Check the channel page — if it shows no live player, wait until the streamer is live and retry","If you wanted a past stream, use the channel's video/clip URL (TrovoVODIE/TrovoChannelIE in newer versions), not the live URL","For 24/7 monitors, catch this expected error and retry on a schedule instead of crashing","Update to yt-dlp for current Trovo support"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(trovo_url)\nexcept ExtractorError as e:\n    if e.expected and 'is offline' in str(e):\n        schedule_retry(trovo_url, interval=300)  # poll until live","preventionTips":["For 24/7 recording, poll the channel and start on first success","Use VOD/clip URLs for finished streams instead of the live URL","Treat offline as transient, not fatal"],"tags":["extractor","livestream","offline","expected"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}