{"record":{"id":"ef23a3975f5c5bf7","repo":"ytdl-org/youtube-dl","slug":"couldn-t-extract-vid-and-key","errorCode":null,"errorMessage":"couldn't extract vid and key","messagePattern":"couldn't extract vid and key","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/naver.py","lineNumber":157,"sourceCode":"\n    def _real_extract(self, url):\n        video_id = self._match_id(url)\n        content = self._download_json(\n            'https://tv.naver.com/api/json/v/' + video_id,\n            video_id, headers=self.geo_verification_headers())\n        player_info_json = content.get('playerInfoJson') or {}\n        current_clip = player_info_json.get('currentClip') or {}\n\n        vid = current_clip.get('videoId')\n        in_key = current_clip.get('inKey')\n\n        if not vid or not in_key:\n            player_auth = try_get(player_info_json, lambda x: x['playerOption']['auth'])\n            if player_auth == 'notCountry':\n                self.raise_geo_restricted(countries=['KR'])\n            elif player_auth == 'notLogin':\n                self.raise_login_required()\n            raise ExtractorError('couldn\\'t extract vid and key')\n        info = self._extract_video_info(video_id, vid, in_key)\n        info.update({\n            'description': clean_html(current_clip.get('description')),\n            'timestamp': int_or_none(current_clip.get('firstExposureTime'), 1000),\n            'duration': parse_duration(current_clip.get('displayPlayTime')),\n            'like_count': int_or_none(current_clip.get('recommendPoint')),\n            'age_limit': 19 if current_clip.get('adult') else None,\n        })\n        return info\n","sourceCodeStart":139,"sourceCodeEnd":167,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/naver.py#L139-L167","documentation":"Raised by Naver's extractor when the page's playerInfoJson.currentClip lacks videoId ('vid') or inKey ('in_key') — the two tokens required to call the video info API. Before raising, it distinguishes auth == 'notCountry' (geo-restricted to KR) and 'notLogin' (login required) via dedicated raises; this generic error fires only when neither applies. It is not expected=True.","triggerScenarios":"currentClip.get('videoId') or currentClip.get('inKey') returns None/empty on a Naver TV/V-LIVE clip page whose playerOption.auth is neither 'notCountry' nor 'notLogin'.","commonSituations":"Naver changing its embedded playerInfoJson shape (rename/removal of keys) so the extractor misses them; clips with unusual delivery types; extractor version lag — by far the most common cause.","solutions":["Update youtube-dl / yt-dlp first — key drift in playerInfoJson is a recurring Naver pattern.","If prompted for login elsewhere, pass cookies: --cookies-from-browser or --cookies <file> so authenticated clips expose vid/inKey.","If the failure came before any auth hint, confirm the clip plays anonymously in a browser from your region; if it needs KR egress, use a KR proxy."],"exampleFix":"# before\nyoutube-dl https://tv.naver.com/v/12345678\n\n# after\nyoutube-dl --cookies-from-browser chrome https://tv.naver.com/v/12345678","handlingStrategy":"try-catch","validationCode":"import requests\nclip = (requests.get(url).json().get('playerInfoJson') or {}).get('currentClip') or {}\nif not clip.get('videoId') or not clip.get('inKey'):\n    auth = (requests.get(url).json().get('playerInfoJson') or {}).get('playerOption', {}).get('auth')\n    print('blocked:', auth or 'unknown/extraction drift')","typeGuard":null,"tryCatchPattern":"from youtube_dl.utils import ExtractorError, GeoRestrictedError\ntry:\n    ydl.extract_info(url)\nexcept GeoRestrictedError:\n    retry_with_proxy(url, region='KR')\nexcept ExtractorError as e:\n    if 'raise_login_required' in str(e) or 'login' in str(e).lower():\n        retry_with_cookies(url)\n    elif \"couldn't extract vid and key\" in str(e):\n        update_or_report(url)  # playerInfoJson shape changed\n    else:\n        raise","preventionTips":["Always pass browser cookies for Naver — many clips are login-gated.","Handle the dedicated GeoRestrictedError/login errors first; this generic error means extractor drift.","Update yt-dlp whenever Naver extraction breaks; key names change frequently."],"tags":["extractor","api-change","korea","authentication"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}