{"record":{"id":"d2aa3cb0992641ad","repo":"yt-dlp/yt-dlp","slug":"unable-to-extract-video-info","errorCode":null,"errorMessage":"Unable to extract video info","messagePattern":"Unable to extract video info","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"yt_dlp/extractor/naver.py","lineNumber":203,"sourceCode":"            'comment_count': int,\n            'duration': 69,\n            'thumbnail': r're:^https?://.*\\.jpg',\n        },\n        'params': {'format': 'HLS_144P'},\n    }, {\n        'url': 'http://tvcast.naver.com/v/81652',\n        'only_matching': True,\n    }]\n\n    def _real_extract(self, url):\n        video_id = self._match_id(url)\n        data = self._call_api(f'/clips/{video_id}/play-info', video_id)\n\n        vid = traverse_obj(data, ('clip', 'videoId', {str}))\n        in_key = traverse_obj(data, ('play', 'inKey', {str}))\n\n        if not vid or not in_key:\n            raise ExtractorError('Unable to extract video info')\n\n        info = self._extract_video_info(video_id, vid, in_key)\n        info.update(traverse_obj(data, ('clip', {\n            'title': 'title',\n            'description': 'description',\n            'timestamp': ('firstExposureDatetime', {parse_iso8601}),\n            'duration': ('playTime', {int_or_none}),\n            'like_count': ('likeItCount', {int_or_none}),\n            'view_count': ('playCount', {int_or_none}),\n            'comment_count': ('commentCount', {int_or_none}),\n            'thumbnail': ('thumbnailImageUrl', {url_or_none}),\n            'uploader': 'channelName',\n            'uploader_id': 'channelId',\n            'uploader_url': ('channelUrl', {url_or_none}),\n            'age_limit': ('adultVideo', {lambda x: 19 if x else None}),\n        })))\n        return info\n","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/yt-dlp/yt-dlp/blob/81ecd58b1394793e6da9998cc19fdb45657f1685/yt_dlp/extractor/naver.py#L185-L221","documentation":"Thrown by NaverIE._real_extract (yt_dlp/extractor/naver.py:203). The TVCAST API call GET /clips/<id>/play-info succeeded, but the response is missing clip.videoId (the real media id) or play.inKey (the playback access key); without both, the follow-up streams endpoint cannot even be requested.","triggerScenarios":"_call_api('/clips/<video_id>/play-info') returns JSON where traverse_obj of ('clip','videoId') or ('play','inKey') comes back empty: clip deleted or privated, region-locked content (Naver frequently restricts to KR), or a changed API schema.","commonSituations":"Clip removed/made private; accessing NaverTV from outside Korea or from datacenter IPs; Naver API changes after site updates; clips that only play in the mobile app.","solutions":["Open the clip URL in a browser (ideally from Korea) and confirm it still plays","Retry with --proxy using a Korean exit node - many Naver clips are KR-only","Pass cookies if the clip requires login","Update yt-dlp to latest nightly","Report with --verbose if the play-info JSON shape changed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import json, urllib.request\n\ndef naver_clip_extractable(video_id) -> bool:\n    api = f'https://tv.naver.com/api/clips/{video_id}/play-info'\n    with urllib.request.urlopen(api) as r:\n        data = json.load(r)\n    return bool(data.get('clip', {}).get('videoId') and data.get('play', {}).get('inKey'))","typeGuard":"def play_info_complete(data: dict) -> bool:\n    return bool(data.get('clip', {}).get('videoId')) and bool(data.get('play', {}).get('inKey'))","tryCatchPattern":"from yt_dlp.utils import ExtractorError\ntry:\n    info = ydl.extract_info(url, download=False)\nexcept ExtractorError as e:\n    if 'Unable to extract video info' in str(e):\n        # missing videoId/inKey: deleted, private, or region-locked clip\n        mark_unavailable(url)","preventionTips":["Pre-check the play-info API for videoId/inKey before queueing Naver clips","Use Korean exit proxies for NaverTV jobs; many clips are KR-only","Distinguish 'field missing' (permanent) from network errors (transient) in your retry logic"],"tags":["yt-dlp","extractor","naver","api-response","korea"],"backgroundTag":"api-response-missing-fields","analyzedSha":"81ecd58b1394793e6da9998cc19fdb45657f1685","analyzedAt":"2026-08-22T12:21:25.439Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}