{"record":{"id":"4e29c4df5190808f","repo":"ytdl-org/youtube-dl","slug":"join-auth-messages","errorCode":null,"errorMessage":"', '.join(auth['messages'])","messagePattern":"', '\\.join\\(auth\\['messages'\\]\\)","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/gaia.py","lineNumber":74,"sourceCode":"\n    def _real_initialize(self):\n        auth = self._get_cookies('https://www.gaia.com/').get('auth')\n        if auth:\n            auth = self._parse_json(\n                compat_urllib_parse_unquote(auth.value),\n                None, fatal=False)\n        if not auth:\n            username, password = self._get_login_info()\n            if username is None:\n                return\n            auth = self._download_json(\n                'https://auth.gaia.com/v1/login',\n                None, data=urlencode_postdata({\n                    'username': username,\n                    'password': password\n                }))\n            if auth.get('success') is False:\n                raise ExtractorError(', '.join(auth['messages']), expected=True)\n        if auth:\n            self._jwt = auth.get('jwt')\n\n    def _real_extract(self, url):\n        display_id, vtype = re.search(self._VALID_URL, url).groups()\n        node_id = self._download_json(\n            'https://brooklyn.gaia.com/pathinfo', display_id, query={\n                'path': 'video/' + display_id,\n            })['id']\n        node = self._download_json(\n            'https://brooklyn.gaia.com/node/%d' % node_id, node_id)\n        vdata = node[vtype]\n        media_id = compat_str(vdata['nid'])\n        title = node['title']\n\n        headers = None\n        if self._jwt:\n            headers = {'Authorization': 'Bearer ' + self._jwt}","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/gaia.py#L56-L92","documentation":"Raised by the Gaia extractor after a successful HTTP POST to https://auth.gaia.com/v1/login when the response JSON contains success=false. The message is built by joining the API's own 'messages' list, so the text comes straight from Gaia's auth service. It is marked expected=True, meaning youtube-dl treats it as a user-facing failure (bad credentials), not a bug.","triggerScenarios":"Calling a gaia.com URL with --username/--password (or netrc) where Gaia's /v1/login returns {\"success\": false, \"messages\": [\"Invalid username or password\"]}. Only fires when a cached auth cookie is absent and login info was supplied; without credentials the extractor silently returns instead.","commonSituations":"Wrong or expired password, account locked, Gaia changing its auth API response shape, 2FA-only accounts, or a stale GLBID-style auth cookie forcing a fresh login path.","solutions":["Verify the Gaia username/password (try logging in at gaia.com in a browser)","Update stored credentials via --username/--password or ~/.netrc","If credentials are correct, check auth.gaia.com/v1/login manually with curl to see the raw 'messages' payload and confirm the API contract changed","Update to a newer youtube-dl/yt-dlp where the Gaia extractor may be fixed"],"exampleFix":"# before (wrong credentials supplied)\nyoutube-dl --username me --password wrong https://www.gaia.com/video/123\n# after\neyoutube-dl --username me --password correct https://www.gaia.com/video/123\n# or omit credentials if the video is free\tyoutube-dl https://www.gaia.com/video/123","handlingStrategy":"try-catch","validationCode":"import requests\nresp = requests.post('https://auth.gaia.com/v1/login', data={'username': u, 'password': p})\nbody = resp.json()\nif body.get('success') is False:\n    print('Gaia login would fail:', ', '.join(body.get('messages', [])))","typeGuard":"def gaia_auth_ok(auth):\n    return isinstance(auth, dict) and auth.get('success') is not False and 'jwt' in auth","tryCatchPattern":"from youtube_dl.utils import DownloadError\ntry:\n    ydl.extract_info(url, download=True)\nexcept DownloadError as e:\n    if 'Gaia' in str(e) or 'login' in str(e).lower():\n        # expected auth failure: fix credentials, not a bug\n        log_auth_failure(e)\n    else:\n        raise","preventionTips":["Keep Gaia credentials in ~/.netrc with correct permissions instead of CLI flags","Pre-verify login works in a browser before batch jobs","Cache a valid session where supported so login is attempted rarely"],"tags":["authentication","gaia","extractor","login"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}