{"record":{"id":"de1d01716198a56f","repo":"ytdl-org/youtube-dl","slug":"unable-to-log-in","errorCode":null,"errorMessage":"Unable to log in","messagePattern":"Unable to log in","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/bbc.py","lineNumber":296,"sourceCode":"        login_form.update({\n            'username': username,\n            'password': password,\n        })\n\n        post_url = urljoin(self._LOGIN_URL, self._search_regex(\n            r'<form[^>]+action=([\"\\'])(?P<url>.+?)\\1', login_page,\n            'post url', default=self._LOGIN_URL, group='url'))\n\n        response, urlh = self._download_webpage_handle(\n            post_url, None, 'Logging in', data=urlencode_postdata(login_form),\n            headers={'Referer': self._LOGIN_URL})\n\n        if self._LOGIN_URL in urlh.geturl():\n            error = clean_html(get_element_by_class('form-message', response))\n            if error:\n                raise ExtractorError(\n                    'Unable to login: %s' % error, expected=True)\n            raise ExtractorError('Unable to log in')\n\n    def _real_initialize(self):\n        self._login()\n\n    class MediaSelectionError(Exception):\n        def __init__(self, id):\n            self.id = id\n\n    def _extract_asx_playlist(self, connection, programme_id):\n        asx = self._download_xml(connection.get('href'), programme_id, 'Downloading ASX playlist')\n        return [ref.get('href') for ref in asx.findall('./Entry/ref')]\n\n    def _extract_items(self, playlist):\n        return playlist.findall('./{%s}item' % self._EMP_PLAYLIST_NS)\n\n    def _extract_medias(self, media_selection):\n        error = media_selection.get('result')\n        if error:","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/bbc.py#L278-L314","documentation":"The fallback branch of BBCCoUkIE._login: the login POST ended up back on the sign-in page (self._LOGIN_URL appears in the response URL) but no element with class 'form-message' could be extracted from the returned HTML. Unlike its sibling error 42, there is no scraped reason, so the extractor can only report the bare failure. This usually means the page structure changed or the response was an empty/JS-rendered page rather than a credential rejection.","triggerScenarios":"Login POST redirects back to the sign-in URL AND the response HTML lacks a form-message element — e.g. BBC renders errors via JavaScript after page load, returns an interstitial/captcha page, or the scraped form action posted to a URL that bounces silently back to sign-in.","commonSituations":"BBC redesigned the sign-in page and renamed the error CSS class; bot detection serving a challenge page instead of the normal form response; cookies from a previous session confusing the flow; the form action regex matched the wrong form on the page.","solutions":["Verify manually in a browser (with devtools) what the failed-login response looks like; confirm whether the error text still lives in class 'form-message'.","Clear cached cookies and retry login from a clean session.","Confirm the credentials are valid; a silent bounce can still be a credential failure with the message moved client-side.","If the class name changed, update get_element_by_class('form-message', response) in bbc.py:296 to the new selector; report upstream if so.","Skip login entirely — most BBC programmes extract anonymously."],"exampleFix":"// before\nif self._LOGIN_URL in urlh.geturl():\n    error = clean_html(get_element_by_class('form-message', response))\n    if error:\n        raise ExtractorError('Unable to login: %s' % error, expected=True)\n    raise ExtractorError('Unable to log in')\n\n// after\nif self._LOGIN_URL in urlh.geturl():\n    error = clean_html(get_element_by_class('form-message', response))\n    if error:\n        raise ExtractorError('Unable to login: %s' % error, expected=True)\n    raise ExtractorError('Unable to log in: sign-in page re-served without an error message; the BBC login flow may have changed', expected=True)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    ydl.extract_info(url, username=USER, password=PASS)\nexcept ExtractorError as e:\n    if str(e) == 'Unable to log in':\n        # silent bounce: clear cookies and retry once, then give up\n        clear_cookie_file()\n        retry_once(url, anonymous=True)\n    else:\n        raise","preventionTips":["Clear cached cookies between attempts so a stale session cannot silently bounce.","If this appears with valid credentials, assume a BBC flow change and update the extractor rather than retrying.","Prefer anonymous extraction; only debug login when geo/personalised content is required."],"tags":["bbc","authentication","login","silent-failure","extractor"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}