{"record":{"id":"f833dffa332ac97a","repo":"ytdl-org/youtube-dl","slug":"data-get-message-or-code","errorCode":null,"errorMessage":"data.get('message') or code","messagePattern":"data\\.get\\('message'\\) or code","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/canvas.py","lineNumber":80,"sourceCode":"        if not data:\n            headers = self.geo_verification_headers()\n            headers.update({'Content-Type': 'application/json'})\n            token = self._download_json(\n                '%s/tokens' % self._REST_API_BASE, video_id,\n                'Downloading token', data=b'', headers=headers)['vrtPlayerToken']\n            data = self._download_json(\n                '%s/videos/%s' % (self._REST_API_BASE, video_id),\n                video_id, 'Downloading video JSON', query={\n                    'vrtPlayerToken': token,\n                    'client': '%s@PROD' % site_id,\n                }, expected_status=400)\n            if not data.get('title'):\n                code = data.get('code')\n                if code == 'AUTHENTICATION_REQUIRED':\n                    self.raise_login_required()\n                elif code == 'INVALID_LOCATION':\n                    self.raise_geo_restricted(countries=['BE'])\n                raise ExtractorError(data.get('message') or code, expected=True)\n\n        title = data['title']\n        description = data.get('description')\n\n        formats = []\n        for target in data['targetUrls']:\n            format_url, format_type = url_or_none(target.get('url')), str_or_none(target.get('type'))\n            if not format_url or not format_type:\n                continue\n            format_type = format_type.upper()\n            if format_type in self._HLS_ENTRY_PROTOCOLS_MAP:\n                formats.extend(self._extract_m3u8_formats(\n                    format_url, video_id, 'mp4', self._HLS_ENTRY_PROTOCOLS_MAP[format_type],\n                    m3u8_id=format_type, fatal=False))\n            elif format_type == 'HDS':\n                formats.extend(self._extract_f4m_formats(\n                    format_url, video_id, f4m_id=format_type, fatal=False))\n            elif format_type == 'MPEG_DASH':","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/canvas.py#L62-L98","documentation":"Raised by CanvasIE (VRT.be) when the REST video endpoint responds without a 'title'. The request is made with expected_status=400, so HTTP 400 error bodies are parsed normally; if code is AUTHENTICATION_REQUIRED the extractor raises login-required, INVALID_LOCATION raises geo-restricted (BE only), and anything else raises ExtractorError with data['message'] or the code itself.","triggerScenarios":"API responses with codes other than the two handled ones — e.g. VIDEO_NOT_FOUND, expired vrtPlayerToken producing a different error code, or generic API failures. The token is fetched anonymously, so token-bound failures surface here.","commonSituations":"Downloading VRT content from outside Belgium (INVALID_LOCATION is handled as geo, but sibling codes are not); videos that require a VRT account; changed API error schema in a stale youtube-dl.","solutions":["If the message indicates login is needed, pass credentials so raise_login_required paths can be used (or use VRT NU with an account-specific extractor/yt-dlp).","Use a Belgian proxy/VPN for INVALID_LOCATION-class errors: --proxy.","Update to yt-dlp, whose VRT handling is maintained.","Check the exact 'message'/'code' in the exception text — it is the raw API response and pinpoints the cause."],"exampleFix":"try:\n    info = ydl.extract_info(vrt_url, download=False)\nexcept ExtractorError as e:\n    if 'INVALID_LOCATION' in str(e) or 'geo' in str(e).lower():\n        info = ydl.extract_info(vrt_url, download=False, proxy='http://be-proxy:8080')\n    else:\n        raise","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from youtube_dl.utils import ExtractorError, GeoRestrictedError\ntry:\n    info = ydl.extract_info(url, download=False)\nexcept GeoRestrictedError:\n    info = ydl.extract_info(url, download=False, geo_bypass_country='BE')\nexcept ExtractorError as e:\n    if 'AUTHENTICATION_REQUIRED' in str(e):\n        raise NeedsLogin(url)\n    raise","preventionTips":["Surface the raw VRT 'message'/'code' to classify failures (login vs geo vs missing).","Use a Belgian exit node for VRT content.","Provide credentials for login-gated VRT items."],"tags":["canvas","vrt","api-error","geo","auth"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}